Build features for a cancer patient support platform with Next.js frontend, Golang backend, community features, medical records, AI reminders, and HIPAA-compliant security.
A comprehensive digital health platform supporting cancer patients through community support, medical record management, AI-assisted reminders, and telehealth capabilities.
Beautiful Life is a HIPAA-compliant digital health platform with:
```
apps/
frontend/ # Next.js 14 application
backend/ # Golang application
internal/
domain/ # Business entities
application/ # Use cases/services
infrastructure/# External dependencies
interfaces/ # HTTP handlers, DTOs
packages/
shared-types/ # TypeScript types
ui-components/ # React components
```
**Backend (Golang):**
1. Define domain entity in `internal/domain/entity.go`:
```go
type MedicalRecord struct {
ID uuid.UUID
PatientID uuid.UUID
Type RecordType
FileURL string
CreatedAt time.Time
}
```
2. Create repository interface in `internal/domain/repository.go`:
```go
type MedicalRecordRepository interface {
Create(ctx context.Context, record *MedicalRecord) error
GetByPatientID(ctx context.Context, patientID uuid.UUID) ([]*MedicalRecord, error)
}
```
3. Implement service in `internal/application/service.go`:
```go
type MedicalRecordService struct {
repo MedicalRecordRepository
}
func (s *MedicalRecordService) CreateRecord(ctx context.Context, req CreateRecordRequest) (*MedicalRecord, error) {
// Business logic here
return s.repo.Create(ctx, record)
}
```
4. Create HTTP handler in `internal/interfaces/http/handlers/`:
```go
func (h *MedicalRecordHandler) CreateRecord(c *gin.Context) {
var req dto.CreateRecordRequest
if err := c.ShouldBindJSON(&req); err != nil {
c.JSON(http.StatusBadRequest, dto.ErrorResponse{Message: "Invalid input"})
return
}
record, err := h.service.CreateRecord(c.Request.Context(), req)
if err != nil {
c.JSON(http.StatusInternalServerError, dto.ErrorResponse{Message: "Failed to create record"})
return
}
c.JSON(http.StatusCreated, record)
}
```
5. Register route in `internal/interfaces/http/routes/api.go`:
```go
router.POST("/api/v1/medical-records", middleware.AuthRequired(), handler.CreateRecord)
```
**Frontend (Next.js):**
6. Add Next.js API route in `apps/frontend/src/app/api/medical-records/route.ts`:
```typescript
export async function POST(request: Request) {
const body = await request.json();
// Call Golang backend server-side
const response = await fetch(`${process.env.BACKEND_URL}/api/v1/medical-records`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Cookie': request.headers.get('cookie') || '',
},
body: JSON.stringify(body),
});
return response;
}
```
7. Create frontend service in `apps/frontend/src/lib/api.ts`:
```typescript
export async function createMedicalRecord(data: CreateRecordRequest): Promise<MedicalRecord> {
const response = await fetch('/api/medical-records', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
credentials: 'include', // Include HTTP-only cookies
body: JSON.stringify(data),
});
if (!response.ok) throw new Error('Failed to create record');
return response.json();
}
```
8. Write tests for both frontend and backend
1. **Frontend**: Encrypt file client-side before upload:
```typescript
async function uploadMedicalRecord(file: File) {
// Generate encryption key
const key = await crypto.subtle.generateKey(
{ name: 'AES-GCM', length: 256 },
true,
['encrypt', 'decrypt']
);
// Encrypt file
const encrypted = await encryptFile(file, key);
// Upload to S3 via presigned URL
const presignedUrl = await getPresignedUrl();
await uploadToS3(presignedUrl, encrypted);
// Store metadata in database
await createMedicalRecord({
fileUrl: presignedUrl.split('?')[0],
encryptionKeyId: keyId,
type: 'lab_report',
});
}
```
2. **Backend**: Generate presigned URL and store metadata:
```go
func (s *MedicalRecordService) CreatePresignedURL(ctx context.Context, filename string) (string, error) {
req, _ := s.s3Client.PutObjectRequest(&s3.PutObjectInput{
Bucket: aws.String("medical-records"),
Key: aws.String(filename),
})
url, err := req.Presign(15 * time.Minute)
if err != nil {
return "", err
}
// Log access for HIPAA compliance
s.auditLogger.LogAccess(ctx, "presigned_url_generated", filename)
return url, nil
}
```
1. **Domain Model**:
```go
type Reminder struct {
ID uuid.UUID
UserID uuid.UUID
Type ReminderType // medication, appointment, water, etc.
Title string
Description string
Schedule string // cron-like pattern
NextDue time.Time
IsActive bool
}
```
2. **Service Logic**:
```go
func (s *ReminderService) ProcessDueReminders(ctx context.Context) error {
reminders, err := s.repo.GetDueReminders(ctx, time.Now())
if err != nil {
return err
}
for _, reminder := range reminders {
// Send notification
s.notificationService.Send(ctx, reminder.UserID, reminder.Title)
// Log for adherence tracking
s.repo.CreateLog(ctx, &ReminderLog{
ReminderID: reminder.ID,
Status: "sent",
SentAt: time.Now(),
})
// Calculate next due time
nextDue := s.calculateNextDue(reminder.Schedule)
s.repo.UpdateNextDue(ctx, reminder.ID, nextDue)
}
return nil
}
```
3. **Escalation Logic**:
```go
func (s *ReminderService) CheckMissedCriticalReminders(ctx context.Context) error {
missed := s.repo.GetMissedCritical(ctx, 30*time.Minute)
for _, reminder := range missed {
// Notify caregivers
caregivers := s.userService.GetCaregivers(ctx, reminder.UserID)
for _, caregiver := range caregivers {
s.notificationService.SendEscalation(ctx, caregiver.ID, reminder)
}
}
return nil
}
```
1. **Frontend**: Create sharing UI:
```typescript
function ShareRecordModal({ recordId }: { recordId: string }) {
const [recipientEmail, setRecipientEmail] = useState('');
const [permissions, setPermissions] = useState<'view' | 'download' | 'edit'>('view');
const [expiresIn, setExpiresIn] = useState<number>(7); // days
async function handleShare() {
await createMedicalRecordShare({
recordId,
recipientEmail,
permissions,
expiresAt: new Date(Date.now() + expiresIn * 24 * 60 * 60 * 1000),
});
}
return (
<Modal>
<input value={recipientEmail} onChange={e => setRecipientEmail(e.target.value)} />
<select value={permissions} onChange={e => setPermissions(e.target.value)}>
<option value="view">View Only</option>
<option value="download">View & Download</option>
<option value="edit">Full Access</option>
</select>
<button onClick={handleShare}>Share</button>
</Modal>
);
}
```
2. **Backend**: Validate consent and log access:
```go
func (s *MedicalRecordService) CreateShare(ctx context.Context, req CreateShareRequest) error {
// Verify patient owns the record
record, err := s.repo.GetByID(ctx, req.RecordID)
if err != nil || record.PatientID != req.PatientID {
return errors.New("unauthorized")
}
// Create share with expiration
share := &MedicalRecordShare{
RecordID: req.RecordID,
SharedWith: req.RecipientEmail,
Permissions: req.Permissions,
ExpiresAt: req.ExpiresAt,
CreatedBy: req.PatientID,
}
if err := s.repo.CreateShare(ctx, share); err != nil {
return err
}
// HIPAA audit log
s.auditLogger.LogAccess(ctx, "record_shared", map[string]interface{}{
"record_id": req.RecordID,
"shared_with": req.RecipientEmail,
"permissions": req.Permissions,
})
return nil
}
```
1. **Create Community**:
```go
type Community struct {
ID uuid.UUID
Name string
Type CommunityType // public, private, expert_led, regional
Category string // cancer_type, treatment_stage, etc.
Description string
Moderation ModerationLevel
CreatedBy uuid.UUID
}
func (s *CommunityService) CreateCommunity(ctx context.Context, req CreateCommunityRequest) (*Community, error) {
community := &Community{
ID: uuid.New(),
Name: req.Name,
Type: req.Type,
CreatedBy: req.UserID,
Moderation: ModerationModerate,
}
// Add creator as admin
member := &CommunityMember{
CommunityID: community.ID,
UserID: req.UserID,
Role: RoleAdmin,
JoinedAt: time.Now(),
}
tx := s.db.Begin()
if err := tx.Create(community).Error; err != nil {
tx.Rollback()
return nil, err
}
if err := tx.Create(member).Error; err != nil {
tx.Rollback()
return nil, err
}
tx.Commit()
return community, nil
}
```
2. **Join Community with Business Rules**:
```go
func (s *CommunityService) JoinCommunity(ctx context.Context, userID, communityID uuid.UUID) error {
user, _ := s.userService.GetUser(ctx, userID)
// Check subscription limits
if user.Plan == PlanFree {
count, _ := s.repo.GetMembershipCount(ctx, userID)
if count >= 3 {
return errors.New("free users limited to 3 communities")
}
}
member := &CommunityMember{
CommunityID: communityID,
UserID: userID,
Role: RoleMember,
JoinedAt: time.Now(),
}
return s.repo.CreateMember(ctx, member)
}
```
1. **Authentication Middleware**:
```go
func AuthRequired() gin.HandlerFunc {
return func(c *gin.Context) {
token, err := c.Cookie("auth_token")
if err != nil {
c.AbortWithStatusJSON(401, gin.H{"error": "unauthorized"})
return
}
claims, err := validateJWT(token)
if err != nil {
c.AbortWithStatusJSON(401, gin.H{"error": "invalid token"})
return
}
c.Set("user_id", claims.UserID)
c.Set("role", claims.Role)
c.Next()
}
}
```
2. **Input Validation**:
```go
type CreateRecordRequest struct {
Type RecordType `json:"type" binding:"required,oneof=prescription lab_report scan_result"`
Description string `json:"description" binding:"required,min=1,max=500"`
}
if err := c.ShouldBindJSON(&req); err != nil {
c.JSON(400, gin.H{"error": "invalid input"})
return
}
```
3. **HIPAA Audit Logging**:
```go
func (l *AuditLogger) LogAccess(ctx context.Context, action string, metadata map[string]interface{}) {
log := &AuditLog{
UserID: getUserIDFromContext(ctx),
Action: action,
Metadata: metadata,
IPAddress: getIPFromContext(ctx),
Timestamp: time.Now(),
}
l.repo.Create(ctx, log)
}
```
4. **Data Encryption**:
5. **Session Management**:
```go
func TestUserService_RegisterUser(t *testing.T) {
mockRepo := new(MockUserRepository)
service := NewUserService(mockRepo)
req := RegisterRequest{
Email: "[email protected]",
Password: "SecurePass123!",
}
user, err := service.RegisterUser(context.Background(), req)
assert.NoError(t, err)
assert.NotNil(t, user)
assert.Equal(t, req.Email, user.Email)
mockRepo.AssertExpectations(t)
}
```
```typescript
describe('LoginForm', () => {
it('should submit login with valid credentials', async () => {
render(<LoginForm />);
fireEvent.change(screen.getByLabelText('Email'), {
target: { value: '[email protected]' },
});
fireEvent.click(screen.getByRole('button', { name: 'Login' }));
await waitFor(() => {
expect(mockLogin).toHaveBeenCalledWith('[email protected]', 'password');
});
});
});
```
1. **Free users**: 3 communities max, 1 group video session/week, 5 AI messages/day
2. **Premium users**: Unlimited communities/video calls, unlimited AI, 3 caregivers
3. **Healthcare providers**: Can only access patient records with explicit consent
4. **Critical reminders**: Escalate to caregivers if missed for 30+ minutes
5. **Medical record sharing**: Temporary links with expiration and granular permissions
6. **Session timeout**: 15 minutes of inactivity triggers automatic logout
7. **Community moderation**: AI-assisted flagging + human moderator review
```
Browser → Next.js API Routes → Golang Backend → PostgreSQL/Redis
↓ (HTTP-only cookies)
JWT Token Management
```
Never expose the Golang backend URL to the browser. Always proxy through Next.js API routes for security.
Leave a review
No reviews yet. Be the first to review this skill!
# Download SKILL.md from killerskills.ai/api/skills/beautiful-life-digital-health-platform/raw