Milestone: M2 — Platform and Client Admin | SOW Reference: FR5 | Requirement Clarity: ✅ Clear | Dev Status: 🟢 Prototyped in POC (logo/hero image upload to S3 not yet implemented — URL-only today) Moved from
docs/requirements/tasks/organization-branding-implementation.md— this is the original detailed implementation breakdown, unmodified below. Note it specs S3-based file upload (FileUploadService,uploadLogo,uploadHeroImage) which is the flagged gap: confirm this still needs building for M2.
M2-04 Organization Branding Implementation Tasks¶
This document breaks down the implementation tasks for creating the organization branding and email template customization features of the REC Verifiable Credentialing Platform. These features enable staffing companies to customize the appearance of landing pages and emails for credential issuance and verification.
Implementation Strategy¶
The implementation will follow these steps: 1. Enhance the branding entity and create DTOs 2. Implement file upload functionality for logos and images 3. Develop services for branding and email template management 4. Create controllers for branding and email template API endpoints 5. Implement preview functionality for templates
Current Implementation Status¶
The project currently has:
- Branding Entity:
- Basic Branding entity with fields for theme, logo, and hero image
-
Relationship to the Organization entity
-
Email Template Entity:
- Basic EmailTemplate entity with fields for name, subject, and body content
- Relationship to the Organization entity
Backend Tasks¶
Branding DTOs¶
- Create
app/backend/src/admin/dto/branding.dto.ts - Implement UpdateBrandingDto:
- theme (object, optional): Theme settings (colors, fonts, etc.)
- logoS3Key (string, optional): S3 key for logo image
- heroImageS3Key (string, optional): S3 key for hero image
- Implement BrandingResponseDto:
- id (string): Branding ID
- orgId (string): Organization ID
- theme (object): Theme settings
- logoUrl (string): URL for logo image
- heroImageUrl (string): URL for hero image
- createdAt (string): Creation timestamp
- updatedAt (string): Last update timestamp
- Implement ThemeDto:
- primaryColor (string, optional): Primary brand color
- secondaryColor (string, optional): Secondary brand color
- accentColor (string, optional): Accent color
- fontFamily (string, optional): Primary font family
- headingFontFamily (string, optional): Heading font family
- buttonStyle (string, optional): Button style (e.g., "rounded", "square")
Email Template DTOs¶
- Create
app/backend/src/admin/dto/email-template.dto.ts - Implement CreateEmailTemplateDto:
- name (string, required): Template name
- subject (string, required): Email subject
- bodyHtml (string, required): HTML body content
- bodyText (string, required): Plain text body content
- variables (array, optional): Allowed placeholder variables
- Implement UpdateEmailTemplateDto:
- name (string, optional): Template name
- subject (string, optional): Email subject
- bodyHtml (string, optional): HTML body content
- bodyText (string, optional): Plain text body content
- variables (array, optional): Allowed placeholder variables
- Implement EmailTemplateResponseDto:
- id (string): Template ID
- orgId (string): Organization ID
- name (string): Template name
- subject (string): Email subject
- bodyHtml (string): HTML body content
- bodyText (string): Plain text body content
- variables (array): Allowed placeholder variables
- createdAt (string): Creation timestamp
- updatedAt (string): Last update timestamp
File Upload Service¶
- Create
app/backend/src/admin/services/file-upload.service.ts - Implement constructor with dependencies:
- Inject ConfigService for accessing S3 configuration
- Inject LoggerService for logging
- Implement uploadFile method:
- Parameters: file (Buffer), folder (string), metadata (object)
- Returns: Promise
(S3 file key) - Generate a unique file key
- Upload the file to S3
- Log the upload operation
- Implement getFileUrl method:
- Parameters: fileKey (string)
- Returns: string (presigned URL)
- Generate a presigned URL for the file
- Implement deleteFile method:
- Parameters: fileKey (string)
- Returns: Promise
- Delete the file from S3
- Log the delete operation
Branding Service¶
- Create
app/backend/src/admin/services/branding.service.ts - Implement constructor with dependencies:
- Inject BrandingRepository
- Inject FileUploadService
- Inject LoggerService
- Implement getBranding method:
- Parameters: organizationId (string)
- Returns: Promise
- Get branding for an organization
- If not found, return default branding
- Implement updateBranding method:
- Parameters: organizationId (string), updateBrandingDto (UpdateBrandingDto)
- Returns: Promise
- Update branding for an organization
- Log the update operation
- Implement uploadLogo method:
- Parameters: organizationId (string), file (Buffer), mimeType (string)
- Returns: Promise
- Upload logo to S3
- Update branding with new logo S3 key
- Log the upload operation
- Implement uploadHeroImage method:
- Parameters: organizationId (string), file (Buffer), mimeType (string)
- Returns: Promise
- Upload hero image to S3
- Update branding with new hero image S3 key
- Log the upload operation
- Implement getDefaultBranding method:
- Returns: Branding
- Return default branding settings
Email Template Service¶
- Create
app/backend/src/admin/services/email-template.service.ts - Implement constructor with dependencies:
- Inject EmailTemplateRepository
- Inject LoggerService
- Implement createEmailTemplate method:
- Parameters: organizationId (string), createEmailTemplateDto (CreateEmailTemplateDto)
- Returns: Promise
- Create a new email template
- Validate HTML content
- Log the creation operation
- Implement getEmailTemplates method:
- Parameters: organizationId (string), filters (object)
- Returns: Promise<[EmailTemplate[], number]>
- Get email templates with pagination and filtering
- Implement getEmailTemplateById method:
- Parameters: id (string)
- Returns: Promise
- Get a single email template by ID
- Implement updateEmailTemplate method:
- Parameters: id (string), updateEmailTemplateDto (UpdateEmailTemplateDto)
- Returns: Promise
- Update the email template
- Validate HTML content
- Log the update operation
- Implement deleteEmailTemplate method:
- Parameters: id (string)
- Returns: Promise
- Delete the email template
- Log the delete operation
- Implement previewEmailTemplate method:
- Parameters: id (string), data (object)
- Returns: { subject: string, bodyHtml: string, bodyText: string }
- Replace variables in the template with provided data
- Return the rendered template
- Implement getDefaultTemplates method:
- Parameters: templateType (string)
- Returns: Promise
- Return default email templates for different purposes
Branding Controller¶
- Create
app/backend/src/admin/controllers/branding.controller.ts - Implement constructor with dependencies:
- Inject BrandingService
- Implement getBranding endpoint:
- GET /organizations/:id/branding
- Parameters: organizationId (path)
- Returns: BrandingResponseDto
- Add @Roles decorator to restrict access to appropriate roles
- Add Swagger documentation
- Implement updateBranding endpoint:
- PUT /organizations/:id/branding
- Parameters: organizationId (path), updateBrandingDto (body)
- Returns: BrandingResponseDto
- Add @Roles decorator to restrict access to appropriate roles
- Add validation using class-validator
- Add Swagger documentation
- Implement uploadLogo endpoint:
- POST /organizations/:id/branding/logo
- Parameters: organizationId (path), file (multipart/form-data)
- Returns: BrandingResponseDto
- Add @Roles decorator to restrict access to appropriate roles
- Add Swagger documentation
- Implement uploadHeroImage endpoint:
- POST /organizations/:id/branding/hero-image
- Parameters: organizationId (path), file (multipart/form-data)
- Returns: BrandingResponseDto
- Add @Roles decorator to restrict access to appropriate roles
- Add Swagger documentation
Email Template Controller¶
- Create
app/backend/src/admin/controllers/email-template.controller.ts - Implement constructor with dependencies:
- Inject EmailTemplateService
- Implement createEmailTemplate endpoint:
- POST /organizations/:id/email-templates
- Parameters: organizationId (path), createEmailTemplateDto (body)
- Returns: EmailTemplateResponseDto
- Add @Roles decorator to restrict access to appropriate roles
- Add validation using class-validator
- Add Swagger documentation
- Implement getEmailTemplates endpoint:
- GET /organizations/:id/email-templates
- Parameters: organizationId (path), pagination and filter params (query)
- Returns: Array of EmailTemplateResponseDto
- Add @Roles decorator to restrict access to appropriate roles
- Add Swagger documentation
- Implement getEmailTemplateById endpoint:
- GET /organizations/:id/email-templates/:templateId
- Parameters: organizationId (path), templateId (path)
- Returns: EmailTemplateResponseDto
- Add @Roles decorator to restrict access to appropriate roles
- Add Swagger documentation
- Implement updateEmailTemplate endpoint:
- PUT /organizations/:id/email-templates/:templateId
- Parameters: organizationId (path), templateId (path), updateEmailTemplateDto (body)
- Returns: EmailTemplateResponseDto
- Add @Roles decorator to restrict access to appropriate roles
- Add validation using class-validator
- Add Swagger documentation
- Implement deleteEmailTemplate endpoint:
- DELETE /organizations/:id/email-templates/:templateId
- Parameters: organizationId (path), templateId (path)
- Returns: void
- Add @Roles decorator to restrict access to appropriate roles
- Add Swagger documentation
- Implement previewEmailTemplate endpoint:
- POST /organizations/:id/email-templates/:templateId/preview
- Parameters: organizationId (path), templateId (path), previewData (body)
- Returns: { subject: string, bodyHtml: string, bodyText: string }
- Add @Roles decorator to restrict access to appropriate roles
- Add Swagger documentation
Unit Tests¶
- Create
app/backend/src/admin/services/branding.service.spec.ts - Test getBranding method
- Test updateBranding method
- Test uploadLogo method
-
Test uploadHeroImage method
-
Create
app/backend/src/admin/services/email-template.service.spec.ts - Test createEmailTemplate method
- Test getEmailTemplates method
- Test getEmailTemplateById method
- Test updateEmailTemplate method
- Test deleteEmailTemplate method
- Test previewEmailTemplate method
Frontend Tasks¶
Branding Configuration UI¶
- Create
app/frontend/src/components/branding/BrandingForm.tsx - Implement form with the following sections:
- Color picker for theme colors
- Font selector for typography
- Logo upload with preview
- Hero image upload with preview
- Add validation for all inputs
- Implement form submission to API
- Add success/error handling
- Add preview functionality
Email Template Editor UI¶
- Create
app/frontend/src/components/email-templates/TemplateEditor.tsx - Implement editor with the following features:
- Rich text editor for HTML content
- Plain text editor for text content
- Subject line input
- Variable insertion dropdown
- Preview functionality
- Add validation for all inputs
- Implement form submission to API
- Add success/error handling
Email Template List UI¶
- Create
app/frontend/src/components/email-templates/TemplateList.tsx - Implement list with the following features:
- Template name and type
- Creation and update dates
- Edit and delete buttons
- Preview button
- Add filtering and sorting options
- Implement pagination
- Add search functionality
Email Template Preview UI¶
- Create
app/frontend/src/components/email-templates/TemplatePreview.tsx - Implement preview with the following features:
- Rendered HTML preview
- Plain text preview
- Test data input form
- Send test email button
- Add responsive design for mobile and desktop preview
Dependencies & Assumptions¶
Prerequisites¶
- The Branding entity must be properly defined
- The EmailTemplate entity must be properly defined
- S3 or equivalent storage must be available for file storage
- Email service must be available for sending test emails
Cross-team Needs¶
- Frontend team needs to implement the UI components
- DevOps team needs to configure S3 or equivalent storage
- QA team needs to test the branding and email template functionality
Implementation Notes¶
- Security Considerations:
- All uploaded files must be scanned for malware
- HTML content must be sanitized to prevent XSS attacks
-
Access to branding and email templates must be restricted to authorized users
-
Performance Considerations:
- Image uploads should be optimized for web use
- Email template rendering should be efficient
-
File URLs should be cached where appropriate
-
Usability Considerations:
- Preview functionality should accurately represent the final output
- Variable insertion should be intuitive
-
Color picker should include common presets
-
Testing Requirements:
- Unit tests should cover all service methods
- Integration tests should verify the complete workflow
- Visual tests should verify the rendering of templates