Docs: Add backend deployment constraints and monorepo structure
- Documented Docker/Kubernetes deployment requirements - Added homelab configuration (resource limits, ports) - Configured reverse proxy compatibility - Designed monorepo structure (backend/mobile/web/shared)
This commit is contained in:
parent
1e38fe3ace
commit
1cf927f527
3 changed files with 1232 additions and 79 deletions
213
README.md
213
README.md
|
|
@ -1,94 +1,149 @@
|
||||||
# Normogen
|
### /home/asoliver/desarrollo/normogen/README.md
|
||||||
|
```markdown
|
||||||
|
1: # Normogen
|
||||||
|
2:
|
||||||
|
3: ## Overview
|
||||||
|
4:
|
||||||
|
5: Normogen is a privacy-focused health data tracking and management platform. The name comes from Mapudungun, relating to Balanced Life.
|
||||||
|
6:
|
||||||
|
7: ## Vision
|
||||||
|
8:
|
||||||
|
9: To record as many variables related to health as possible, store them in a secure, private manner, to be used by you, not by corporations. From medication reminders to pattern analysis, Normogen puts you in control of your health data.
|
||||||
|
10:
|
||||||
|
11: ## Technology Stack
|
||||||
|
12:
|
||||||
|
13: ### Backend
|
||||||
|
14: - **Framework**: Axum 0.7.x
|
||||||
|
15: - **Runtime**: Tokio 1.x
|
||||||
|
16: - **Middleware**: Tower, Tower-HTTP
|
||||||
|
17: - **Database**: MongoDB (with zero-knowledge encryption)
|
||||||
|
18: - **Language**: Rust
|
||||||
|
19:
|
||||||
|
20: ### Mobile (iOS + Android)
|
||||||
|
21: - **Framework**: React Native 0.73+
|
||||||
|
22: - **Language**: TypeScript
|
||||||
|
23: - **State Management**: Redux Toolkit 2.x
|
||||||
|
24: - **Data Fetching**: RTK Query 2.x
|
||||||
|
25: - **Health Sensors**: react-native-health, react-native-google-fit
|
||||||
|
26: - **Encryption**: react-native-quick-crypto
|
||||||
|
27:
|
||||||
|
28: ### Web
|
||||||
|
29: - **Framework**: React 18+
|
||||||
|
30: - **Language**: TypeScript
|
||||||
|
31: - **State Management**: Redux Toolkit 2.x
|
||||||
|
32: - **Data Fetching**: RTK Query 2.x
|
||||||
|
33: - **Charts**: Recharts
|
||||||
|
34:
|
||||||
|
35: ### Deployment
|
||||||
|
36: - Docker on Linux
|
||||||
|
37:
|
||||||
|
38: ## Platform Strategy
|
||||||
|
39:
|
||||||
|
40: **Primary: Mobile Apps** - Daily health tracking, sensor integration, QR scanning, push notifications
|
||||||
|
41:
|
||||||
|
42: **Secondary: Web Browser** - Extensive reporting, visualization, profile management
|
||||||
|
43:
|
||||||
|
44: ## Key Features
|
||||||
|
45:
|
||||||
|
46: - Zero-knowledge encryption
|
||||||
|
47: - Multi-person profiles
|
||||||
|
48: - Family structure management
|
||||||
|
49: - Secure sharing with expiring links
|
||||||
|
50: - Mobile apps with health sensor integration
|
||||||
|
51: - Web interface for complex visualizations
|
||||||
|
52:
|
||||||
|
53: ## Security Model
|
||||||
|
54:
|
||||||
|
55: - Client-side encryption: Data encrypted before leaving device
|
||||||
|
56: - Zero-knowledge: Server stores only encrypted data
|
||||||
|
57: - Proton-style encryption: AES-256-GCM with PBKDF2 key derivation
|
||||||
|
58: - Shareable links: Self-contained decryption keys in URLs
|
||||||
|
59: - Privacy-first: No data selling, subscription-based revenue
|
||||||
|
60:
|
||||||
|
61: ## Documentation
|
||||||
|
62:
|
||||||
|
63: - [Introduction](./introduction.md) - Project vision and detailed feature specification
|
||||||
|
64: - [Encryption Implementation Guide](./encryption.md) - Zero-knowledge encryption architecture
|
||||||
|
65: - [Research](./thoughts/research/) - Technical research and planning documents
|
||||||
|
66:
|
||||||
|
67: ## Development Status
|
||||||
|
68:
|
||||||
|
69: Phase: Planning/Documentation
|
||||||
|
70:
|
||||||
|
71: ### Completed
|
||||||
|
72: - Project vision and requirements
|
||||||
|
73: - Security architecture design
|
||||||
|
74: - Encryption implementation guide
|
||||||
|
75: - Git repository initialization
|
||||||
|
76: - **Rust framework selection: Axum**
|
||||||
|
77: - **Mobile/Web framework selection: React Native + React**
|
||||||
|
78: - **State management selection: Redux Toolkit 2.x**
|
||||||
|
79:
|
||||||
|
80: ### Next Steps
|
||||||
|
81: - Authentication system design (JWT with recovery phrases)
|
||||||
|
82: - Database schema design
|
||||||
|
83: - Create proof-of-concept with Axum
|
||||||
|
84: - Implement basic CRUD API
|
||||||
|
85: - Build mobile apps with health sensor integration
|
||||||
|
86: - Build web companion app
|
||||||
|
87: - Add encryption layer
|
||||||
|
88: - Implement sharing functionality
|
||||||
|
89:
|
||||||
|
90: ## Open Source
|
||||||
|
91:
|
||||||
|
92: Normogen is open-source. Both server and client code will be publicly available.
|
||||||
|
93:
|
||||||
|
94: Note: This project is currently in the planning phase. No implementation code has been written yet.
|
||||||
|
```
|
||||||
|
|
||||||
## Overview
|
|
||||||
|
|
||||||
Normogen is a privacy-focused health data tracking and management platform. The name comes from Mapudungun, relating to Balanced Life.
|
## Monorepo Structure
|
||||||
|
|
||||||
## Vision
|
This is a **monorepo** containing backend, mobile, web, and shared code:
|
||||||
|
|
||||||
To record as many variables related to health as possible, store them in a secure, private manner, to be used by you, not by corporations. From medication reminders to pattern analysis, Normogen puts you in control of your health data.
|
```
|
||||||
|
normogen/
|
||||||
|
├── backend/ # Rust backend (Axum + MongoDB)
|
||||||
|
├── mobile/ # React Native (iOS + Android)
|
||||||
|
├── web/ # React web app
|
||||||
|
├── shared/ # Shared TypeScript code
|
||||||
|
└── thoughts/ # Research & design docs
|
||||||
|
```
|
||||||
|
|
||||||
## Technology Stack
|
Each platform has its own `src/` directory to keep codebases separate while sharing common code through the `shared/` directory.
|
||||||
|
|
||||||
### Backend
|
## Repository Management
|
||||||
- **Framework**: Axum 0.7.x
|
|
||||||
- **Runtime**: Tokio 1.x
|
|
||||||
- **Middleware**: Tower, Tower-HTTP
|
|
||||||
- **Database**: MongoDB (with zero-knowledge encryption)
|
|
||||||
- **Language**: Rust
|
|
||||||
|
|
||||||
### Mobile (iOS + Android)
|
- **Git Hosting**: Forgejo (self-hosted)
|
||||||
- **Framework**: React Native 0.73+
|
- **CI/CD**: Forgejo Actions
|
||||||
- **Language**: TypeScript
|
- **Branch Strategy**: `main`, `develop`, `feature/*`
|
||||||
- **State Management**: Redux Toolkit 2.x
|
- **Deployment**: Docker Compose (homelab), Kubernetes (future)
|
||||||
- **Data Fetching**: RTK Query 2.x
|
|
||||||
- **Health Sensors**: react-native-health, react-native-google-fit
|
|
||||||
- **Encryption**: react-native-quick-crypto
|
|
||||||
|
|
||||||
### Web
|
## Deployment
|
||||||
- **Framework**: React 18+
|
|
||||||
- **Language**: TypeScript
|
|
||||||
- **State Management**: Redux Toolkit 2.x
|
|
||||||
- **Data Fetching**: RTK Query 2.x
|
|
||||||
- **Charts**: Recharts
|
|
||||||
|
|
||||||
### Deployment
|
### Backend Deployment
|
||||||
- Docker on Linux
|
|
||||||
|
|
||||||
## Platform Strategy
|
```bash
|
||||||
|
# Clone repository
|
||||||
|
git clone <forgejo-url> normogen
|
||||||
|
cd normogen/backend
|
||||||
|
|
||||||
**Primary: Mobile Apps** - Daily health tracking, sensor integration, QR scanning, push notifications
|
# Setup configuration
|
||||||
|
cp config/.env.example config/.env
|
||||||
|
# Edit config/.env
|
||||||
|
|
||||||
**Secondary: Web Browser** - Extensive reporting, visualization, profile management
|
# Build and run
|
||||||
|
docker compose build
|
||||||
|
docker compose up -d
|
||||||
|
|
||||||
## Key Features
|
# Check status
|
||||||
|
curl http://localhost:6000/health
|
||||||
|
```
|
||||||
|
|
||||||
- Zero-knowledge encryption
|
**Resource Limits** (Homelab):
|
||||||
- Multi-person profiles
|
- CPU: 1000m (1 core)
|
||||||
- Family structure management
|
- Memory: 1000Mi (1GB RAM)
|
||||||
- Secure sharing with expiring links
|
|
||||||
- Mobile apps with health sensor integration
|
|
||||||
- Web interface for complex visualizations
|
|
||||||
|
|
||||||
## Security Model
|
**Ports**:
|
||||||
|
- Backend API: `6000` (host) → `8000` (container)
|
||||||
- Client-side encryption: Data encrypted before leaving device
|
- MongoDB: `27017` (standard port)
|
||||||
- Zero-knowledge: Server stores only encrypted data
|
|
||||||
- Proton-style encryption: AES-256-GCM with PBKDF2 key derivation
|
|
||||||
- Shareable links: Self-contained decryption keys in URLs
|
|
||||||
- Privacy-first: No data selling, subscription-based revenue
|
|
||||||
|
|
||||||
## Documentation
|
|
||||||
|
|
||||||
- [Introduction](./introduction.md) - Project vision and detailed feature specification
|
|
||||||
- [Encryption Implementation Guide](./encryption.md) - Zero-knowledge encryption architecture
|
|
||||||
- [Research](./thoughts/research/) - Technical research and planning documents
|
|
||||||
|
|
||||||
## Development Status
|
|
||||||
|
|
||||||
Phase: Planning/Documentation
|
|
||||||
|
|
||||||
### Completed
|
|
||||||
- Project vision and requirements
|
|
||||||
- Security architecture design
|
|
||||||
- Encryption implementation guide
|
|
||||||
- Git repository initialization
|
|
||||||
- **Rust framework selection: Axum**
|
|
||||||
- **Mobile/Web framework selection: React Native + React**
|
|
||||||
- **State management selection: Redux Toolkit 2.x**
|
|
||||||
|
|
||||||
### Next Steps
|
|
||||||
- Authentication system design (JWT with recovery phrases)
|
|
||||||
- Database schema design
|
|
||||||
- Create proof-of-concept with Axum
|
|
||||||
- Implement basic CRUD API
|
|
||||||
- Build mobile apps with health sensor integration
|
|
||||||
- Build web companion app
|
|
||||||
- Add encryption layer
|
|
||||||
- Implement sharing functionality
|
|
||||||
|
|
||||||
## Open Source
|
|
||||||
|
|
||||||
Normogen is open-source. Both server and client code will be publicly available.
|
|
||||||
|
|
||||||
Note: This project is currently in the planning phase. No implementation code has been written yet.
|
|
||||||
|
|
|
||||||
786
thoughts/research/2026-02-14-backend-deployment-constraints.md
Normal file
786
thoughts/research/2026-02-14-backend-deployment-constraints.md
Normal file
|
|
@ -0,0 +1,786 @@
|
||||||
|
### /home/asoliver/desarrollo/normogen/thoughts/research/2026-02-14-backend-deployment-constraints.md
|
||||||
|
```markdown
|
||||||
|
1: # Backend Deployment Constraints
|
||||||
|
2:
|
||||||
|
3: ## Deployment Requirements
|
||||||
|
4:
|
||||||
|
5: ### Docker + Docker Compose
|
||||||
|
6: - Backend must be containerized using Docker
|
||||||
|
7: - Use Docker Compose for local development and homelab deployment
|
||||||
|
8: - Multi-stage builds for optimal image size
|
||||||
|
9: - Non-root user for security
|
||||||
|
10:
|
||||||
|
11: ### Kubernetes Compatibility
|
||||||
|
12: - Design for future Kubernetes deployment
|
||||||
|
13: - Use environment-based configuration (env vars)
|
||||||
|
14: - Health check endpoints (`/health`, `/ready`)
|
||||||
|
15: - Graceful shutdown handling
|
||||||
|
16: - Stateless application design
|
||||||
|
17: - ConfigMap and Secret ready
|
||||||
|
18:
|
||||||
|
19: ### One-Command Deployment
|
||||||
|
20: ```bash
|
||||||
|
21: # Clone repository
|
||||||
|
22: git clone https://github.com/yourusername/normogen.git
|
||||||
|
23: cd normogen
|
||||||
|
24:
|
||||||
|
25: # Setup configuration
|
||||||
|
26: cp config/example.env config/.env
|
||||||
|
27: # Edit config/.env with your settings
|
||||||
|
28:
|
||||||
|
29: # Build and run
|
||||||
|
30: docker compose build
|
||||||
|
31: docker compose up -d
|
||||||
|
32: ```
|
||||||
|
33:
|
||||||
|
34: ## Homelab Deployment (Phase 1)
|
||||||
|
35:
|
||||||
|
36: ### Port Configuration
|
||||||
|
37: - **MongoDB**: Standard ports
|
||||||
|
38: - Primary: `27017` (default MongoDB port)
|
||||||
|
39: - This allows connecting with existing MongoDB tools/admin UIs
|
||||||
|
40:
|
||||||
|
41: - **Backend API**: `6000` (homelab range)
|
||||||
|
42: - External: `6000` (host port)
|
||||||
|
43: - Internal: `8000` (container port)
|
||||||
|
44: - Mapped in docker-compose.yml
|
||||||
|
45:
|
||||||
|
46: - **Future Services**: Port range `6000-6999`
|
||||||
|
47: - `6000`: Backend API (current)
|
||||||
|
48: - `6001`: Web UI (future)
|
||||||
|
49: - `6002`: Admin dashboard (future)
|
||||||
|
50: - `6003`: Metrics/monitoring (future)
|
||||||
|
51:
|
||||||
|
52: ### Network Configuration
|
||||||
|
53: - Docker network: `normogen-network`
|
||||||
|
54: - Must communicate with existing Docker services on homelab server
|
||||||
|
55: - MongoDB accessible to host for backup/admin tools
|
||||||
|
56:
|
||||||
|
57: ### Environment Configuration
|
||||||
|
58: ```bash
|
||||||
|
59: # config/.env (gitignored)
|
||||||
|
60: # Server Configuration
|
||||||
|
61: RUST_LOG=info
|
||||||
|
62: SERVER_HOST=0.0.0.0
|
||||||
|
63: SERVER_PORT=8000
|
||||||
|
64: ALLOWED_ORIGINS=http://localhost:3000,http://localhost:6001
|
||||||
|
65:
|
||||||
|
66: # Database Configuration
|
||||||
|
67: MONGODB_URI=mongodb://mongodb:27017/normogen
|
||||||
|
68: MONGODB_DATABASE=normogen
|
||||||
|
69:
|
||||||
|
70: # JWT Configuration
|
||||||
|
71: JWT_SECRET=your-super-secret-jwt-key-here
|
||||||
|
72: JWT_ACCESS_TOKEN_EXPIRY_MINUTES=15
|
||||||
|
73: JWT_REFRESH_TOKEN_EXPIRY_DAYS=30
|
||||||
|
74:
|
||||||
|
75: # Encryption Configuration (for validation only)
|
||||||
|
76: # Actual encryption happens client-side
|
||||||
|
77: ENCRYPTION_ALGORITHM=aes-256-gcm
|
||||||
|
78:
|
||||||
|
79: # Rate Limiting
|
||||||
|
80: RATE_LIMIT_REQUESTS=100
|
||||||
|
81: RATE_LIMIT_DURATION_SECONDS=60
|
||||||
|
82: ```
|
||||||
|
83:
|
||||||
|
84: ### Docker Compose Structure
|
||||||
|
85: ```yaml
|
||||||
|
86: # docker-compose.yml
|
||||||
|
87: version: '3.8'
|
||||||
|
88:
|
||||||
|
89: services:
|
||||||
|
90: backend:
|
||||||
|
91: build:
|
||||||
|
92: context: .
|
||||||
|
93: dockerfile: docker/Dockerfile
|
||||||
|
94: container_name: normogen-backend
|
||||||
|
95: ports:
|
||||||
|
96: - "6000:8000" # Homelab port range
|
||||||
|
97: environment:
|
||||||
|
98: - RUST_LOG=${RUST_LOG:-info}
|
||||||
|
99: - SERVER_PORT=8000
|
||||||
|
100: - MONGODB_URI=mongodb://mongodb:27017/normogen
|
||||||
|
101: - MONGODB_DATABASE=${MONGODB_DATABASE:-normogen}
|
||||||
|
102: - JWT_SECRET=${JWT_SECRET}
|
||||||
|
103: - JWT_ACCESS_TOKEN_EXPIRY_MINUTES=${JWT_ACCESS_TOKEN_EXPIRY_MINUTES:-15}
|
||||||
|
104: - JWT_REFRESH_TOKEN_EXPIRY_DAYS=${JWT_REFRESH_TOKEN_EXPIRY_DAYS:-30}
|
||||||
|
105: env_file:
|
||||||
|
106: - config/.env
|
||||||
|
107: depends_on:
|
||||||
|
108: mongodb:
|
||||||
|
109: condition: service_healthy
|
||||||
|
110: networks:
|
||||||
|
111: - normogen-network
|
||||||
|
112: restart: unless-stopped
|
||||||
|
113: healthcheck:
|
||||||
|
114: test: ["CMD", "curl", "-f", "http://localhost:8000/health"]
|
||||||
|
115: interval: 30s
|
||||||
|
116: timeout: 10s
|
||||||
|
117: retries: 3
|
||||||
|
118: start_period: 40s
|
||||||
|
119:
|
||||||
|
120: mongodb:
|
||||||
|
121: image: mongo:6.0
|
||||||
|
122: container_name: normogen-mongodb
|
||||||
|
123: ports:
|
||||||
|
124: - "27017:27017" # Standard MongoDB port
|
||||||
|
125: environment:
|
||||||
|
126: - MONGO_INITDB_DATABASE=${MONGO_DATABASE:-normogen}
|
||||||
|
127: volumes:
|
||||||
|
128: - mongodb_data:/data/db
|
||||||
|
129: - mongodb_config:/data/configdb
|
||||||
|
130: networks:
|
||||||
|
131: - normogen-network
|
||||||
|
132: restart: unless-stopped
|
||||||
|
133: healthcheck:
|
||||||
|
134: test: ["CMD", "mongosh", "--eval", "db.adminCommand('ping')"]
|
||||||
|
135: interval: 10s
|
||||||
|
136: timeout: 5s
|
||||||
|
137: retries: 5
|
||||||
|
138: start_period: 10s
|
||||||
|
139:
|
||||||
|
140: volumes:
|
||||||
|
141: mongodb_data:
|
||||||
|
142: driver: local
|
||||||
|
143: mongodb_config:
|
||||||
|
144: driver: local
|
||||||
|
145:
|
||||||
|
146: networks:
|
||||||
|
147: normogen-network:
|
||||||
|
148: driver: bridge
|
||||||
|
149: ```
|
||||||
|
150:
|
||||||
|
151: ## Kubernetes Deployment (Phase 2 - Future)
|
||||||
|
152:
|
||||||
|
153: ### Manifests Structure
|
||||||
|
154: ```
|
||||||
|
155: k8s/
|
||||||
|
156: ├── base/
|
||||||
|
157: │ ├── deployment.yaml
|
||||||
|
158: │ ├── service.yaml
|
||||||
|
159: │ ├── configmap.yaml
|
||||||
|
160: │ ├── secrets.yaml
|
||||||
|
161: │ └── ingress.yaml
|
||||||
|
162: └── overlays/
|
||||||
|
163: ├── homelab/
|
||||||
|
164: │ ├── kustomization.yaml
|
||||||
|
165: │ └── patches/
|
||||||
|
166: └── production/
|
||||||
|
167: ├── kustomization.yaml
|
||||||
|
168: └── patches/
|
||||||
|
169: ```
|
||||||
|
170:
|
||||||
|
171: ### Deployment Configuration
|
||||||
|
172: - **Replicas**: 2-3 for high availability
|
||||||
|
173: - **Liveness Probe**: `/health` (10s interval, 5s timeout)
|
||||||
|
174: - **Readiness Probe**: `/ready` (5s interval, 3s timeout)
|
||||||
|
175: - **Resource Limits**:
|
||||||
|
176: - CPU: 500m-1000m
|
||||||
|
177: - Memory: 256Mi-512Mi
|
||||||
|
178: - **Helm Chart**: Optional for easier deployment
|
||||||
|
179:
|
||||||
|
180: ### Configuration Management
|
||||||
|
181: - **ConfigMap**: Non-sensitive config (log levels, ports)
|
||||||
|
182: - **Secrets**: Sensitive config (JWT secret, DB URI)
|
||||||
|
183: - **Environment Variables**: All configuration via env vars
|
||||||
|
184:
|
||||||
|
185: ## Dockerfile Design
|
||||||
|
186:
|
||||||
|
187: ### Multi-Stage Build
|
||||||
|
188: ```dockerfile
|
||||||
|
189: # docker/Dockerfile
|
||||||
|
190:
|
||||||
|
191: # Build stage
|
||||||
|
192: FROM rust:1.75-alpine AS builder
|
||||||
|
193: WORKDIR /app
|
||||||
|
194:
|
||||||
|
195: # Install build dependencies
|
||||||
|
196: RUN apk add --no-cache musl-dev pkgconf openssl-dev
|
||||||
|
197:
|
||||||
|
198: # Copy manifests
|
||||||
|
199: COPY Cargo.toml Cargo.lock ./
|
||||||
|
200:
|
||||||
|
201: # Create dummy main.rs to build dependencies
|
||||||
|
202: RUN mkdir src && echo "fn main() {}" > src/main.rs
|
||||||
|
203: RUN cargo build --release && rm -rf src
|
||||||
|
204:
|
||||||
|
205: # Copy source code
|
||||||
|
206: COPY src ./src
|
||||||
|
207:
|
||||||
|
208: # Build application
|
||||||
|
209: RUN touch src/main.rs && cargo build --release
|
||||||
|
210:
|
||||||
|
211: # Runtime stage
|
||||||
|
212: FROM alpine:3.18
|
||||||
|
213: WORKDIR /app
|
||||||
|
214:
|
||||||
|
215: # Install runtime dependencies
|
||||||
|
216: RUN apk add --no-cache ca-certificates openssl
|
||||||
|
217:
|
||||||
|
218: # Copy binary from builder
|
||||||
|
219: COPY --from=builder /app/target/release/normogen-backend /app/normogen-backend
|
||||||
|
220:
|
||||||
|
221: # Create non-root user
|
||||||
|
222: RUN addgroup -g 1000 normogen && \
|
||||||
|
223: adduser -D -u 1000 -G normogen normogen && \
|
||||||
|
224: chown -R normogen:normogen /app
|
||||||
|
225:
|
||||||
|
226: USER normogen
|
||||||
|
227:
|
||||||
|
228: # Expose port
|
||||||
|
229: EXPOSE 8000
|
||||||
|
230:
|
||||||
|
231: # Check
|
||||||
|
232: HEALTHCHECK --interval=30s --timeout=10s --start-period=40s --retries=3 \
|
||||||
|
233: CMD wget --no-verbose --tries=1 --spider http://localhost:8000/health || exit 1
|
||||||
|
234:
|
||||||
|
235: # Run application
|
||||||
|
236: CMD ["./normogen-backend"]
|
||||||
|
237: ```
|
||||||
|
238:
|
||||||
|
239: ## Configuration Management
|
||||||
|
240:
|
||||||
|
241: ### Environment Variables
|
||||||
|
242: All configuration via environment variables (12-factor app):
|
||||||
|
243: - Database connections
|
||||||
|
244: - JWT secrets
|
||||||
|
245: - API credentials
|
||||||
|
246: - Feature flags
|
||||||
|
247: - Log levels
|
||||||
|
248:
|
||||||
|
249: ### Configuration Files
|
||||||
|
250: ```
|
||||||
|
251: config/
|
||||||
|
252: ├── .env # Gitignored, local dev
|
||||||
|
253: ├── .env.example # Git committed, template
|
||||||
|
254: └── defaults.env # Git committed, defaults
|
||||||
|
255: ```
|
||||||
|
256:
|
||||||
|
257: ### Configuration Validation
|
||||||
|
258: - Validate required env vars on startup
|
||||||
|
259: - Fail fast if misconfigured
|
||||||
|
260: - Log configuration (sanitize secrets)
|
||||||
|
261:
|
||||||
|
262: ## Endpoints
|
||||||
|
263:
|
||||||
|
264: ### Check Endpoints
|
||||||
|
265: ```rust
|
||||||
|
266: // GET /health - Liveness probe
|
||||||
|
267: // Returns: {"status": "ok"}
|
||||||
|
268: // Used by: K8s liveness probe, Docker check
|
||||||
|
269: // Purpose: Is the app running?
|
||||||
|
270:
|
||||||
|
271: // GET /ready - Readiness probe
|
||||||
|
272: // Returns: {"status": "ready", "database": "connected"}
|
||||||
|
273: // Used by: K8s readiness probe
|
||||||
|
274: // Purpose: Is the app ready to serve traffic?
|
||||||
|
275: ```
|
||||||
|
276:
|
||||||
|
277: ## Logging & Observability
|
||||||
|
278:
|
||||||
|
279: ### Structured Logging
|
||||||
|
280: - JSON format for production
|
||||||
|
281: - Log levels: ERROR, WARN, INFO, DEBUG, TRACE
|
||||||
|
282: - Request ID tracing
|
||||||
|
283: - Sensitive data sanitization
|
||||||
|
284:
|
||||||
|
285: ### Metrics (Future)
|
||||||
|
286: - Prometheus endpoint: `/metrics`
|
||||||
|
287: - Request rate, error rate, latency
|
||||||
|
288: - Database connection pool status
|
||||||
|
289:
|
||||||
|
290: ## Security Considerations
|
||||||
|
291:
|
||||||
|
292: ### Container Security
|
||||||
|
293: - Non-root user (UID 1000)
|
||||||
|
294: - Read-only filesystem (except /tmp)
|
||||||
|
295: - Minimal base image (Alpine)
|
||||||
|
296: - No shell in runtime image
|
||||||
|
297: - Security scanning (Trivy, Snyk)
|
||||||
|
298:
|
||||||
|
299: ### Secrets Management
|
||||||
|
300: - Never commit secrets to git
|
||||||
|
301: - Use environment variables
|
||||||
|
302: - K8s: Use secrets, not configmaps
|
||||||
|
303: - Docker: Use env_file or Docker secrets
|
||||||
|
304: - Gitignore: `config/.env`
|
||||||
|
305:
|
||||||
|
306: ## Deployment Checklist
|
||||||
|
307:
|
||||||
|
308: ### Initial Setup
|
||||||
|
309: - [ ] Clone repository
|
||||||
|
310: - [ ] Copy `config/.env.example` to `config/.env`
|
||||||
|
311: - [ ] Configure environment variables
|
||||||
|
312: - [ ] Create Docker network: `docker network create normogen-network`
|
||||||
|
313: - [ ] Generate JWT secret: `openssl rand -base64 32`
|
||||||
|
314:
|
||||||
|
315: ### Build & Run
|
||||||
|
316: - [ ] Build: `docker compose build`
|
||||||
|
317: - [ ] Run: `docker compose up -d`
|
||||||
|
318: - [ ] Check logs: `docker compose logs -f backend`
|
||||||
|
319: - [ ] Check status: `curl http://localhost:6000/health`
|
||||||
|
320: - [ ] Check ready: `curl http://localhost:6000/ready`
|
||||||
|
321:
|
||||||
|
322: ### Verification
|
||||||
|
323: - [ ] Backend responds on port 6000
|
||||||
|
324: - [ ] MongoDB accessible on port 27017
|
||||||
|
325: - [ ] Checks passing
|
||||||
|
326: - [ ] Database connection working
|
||||||
|
327: - [ ] JWT authentication working
|
||||||
|
328:
|
||||||
|
329: ## Questions for Clarification
|
||||||
|
330:
|
||||||
|
331: ### Environment
|
||||||
|
332: 1. **Reverse Proxy**: Will you use a reverse proxy (Nginx, Traefik, Caddy)?
|
||||||
|
333: - If yes, should TLS be handled at proxy or backend?
|
||||||
|
334: - What domain/path for the API?
|
||||||
|
335:
|
||||||
|
336: 2. **MongoDB Deployment**:
|
||||||
|
337: - Is MongoDB already running in your homelab?
|
||||||
|
338: - Or should docker-compose spin up a dedicated MongoDB instance for Normogen?
|
||||||
|
339: - If existing: What's the connection string?
|
||||||
|
340:
|
||||||
|
341: 3. **Resource Limits**:
|
||||||
|
342: - Any CPU/memory constraints for the homelab?
|
||||||
|
343: - Suggested limits: 500m CPU, 512Mi RAM?
|
||||||
|
344:
|
||||||
|
345: 4. **Backup Strategy**:
|
||||||
|
346: - MongoDB backups? (Volume mount, scheduled dump)
|
||||||
|
347: - Configuration backups?
|
||||||
|
348:
|
||||||
|
349: 5. **Monitoring**:
|
||||||
|
350: - Log aggregation? (ELK, Loki, Splunk)
|
||||||
|
351: - Metrics collection? (Prometheus, Grafana)
|
||||||
|
352: - APM? (Datadog, New Relic)
|
||||||
|
353:
|
||||||
|
354: 6. **CI/CD**:
|
||||||
|
355: - Will you use GitHub Actions, GitLab CI, or Jenkins?
|
||||||
|
356: - Auto-deploy on commit to main branch?
|
||||||
|
357: - Automated testing before deploy?
|
||||||
|
358:
|
||||||
|
359: ### Development Workflow
|
||||||
|
360: 7. **Hot Reload**: Development mode with hot reload?
|
||||||
|
361: - Use `cargo-watch` for auto-rebuild on file changes?
|
||||||
|
362:
|
||||||
|
363: 8. **Database Migrations**:
|
||||||
|
364: - Run migrations on startup?
|
||||||
|
365: - Separate migration tool?
|
||||||
|
366:
|
||||||
|
367: 9. **Seed Data**:
|
||||||
|
368: - Seed development database with sample data?
|
||||||
|
369:
|
||||||
|
370: ### Production Readiness
|
||||||
|
371: 10. **Rate Limiting**:
|
||||||
|
372: - Per-IP rate limiting?
|
||||||
|
373: - Per-user rate limiting (after auth)?
|
||||||
|
374:
|
||||||
|
375: 11. **CORS Configuration**:
|
||||||
|
376: - Allowed origins for local dev?
|
||||||
|
377: - Allowed origins for production?
|
||||||
|
378:
|
||||||
|
379: 12. **TLS/HTTPS**:
|
||||||
|
380: - Local dev: HTTP or HTTPS?
|
||||||
|
381: - Production: TLS termination at proxy?
|
||||||
|
382:
|
||||||
|
383: ## Next Steps
|
||||||
|
384:
|
||||||
|
385: Once the above questions are answered, we can proceed with:
|
||||||
|
386:
|
||||||
|
387: 1. **Phase 2.1**: Docker Compose Setup
|
||||||
|
388: - Create Dockerfile (multi-stage build)
|
||||||
|
389: - Create docker-compose.yml
|
||||||
|
390: - Create configuration templates
|
||||||
|
391: - Test local deployment
|
||||||
|
392:
|
||||||
|
393: 2. **Phase 2.2**: Axum Server Setup
|
||||||
|
394: - Initialize Rust project
|
||||||
|
395: - Setup Axum dependencies
|
||||||
|
396: - Create check endpoints
|
||||||
|
397: - Test containerized build
|
||||||
|
398:
|
||||||
|
399: 3. **Phase 2.3**: MongoDB Integration
|
||||||
|
400: - MongoDB connection pooling
|
||||||
|
401: - Readiness check with database
|
||||||
|
402: - Test database connectivity
|
||||||
|
403:
|
||||||
|
404: 4. **Phase 2.4**: Configuration Management
|
||||||
|
405: - Environment variable validation
|
||||||
|
406: - Configuration struct
|
||||||
|
407: - Secret loading
|
||||||
|
408:
|
||||||
|
409: 5. **Phase 2.5**: Deployment Testing
|
||||||
|
410: - Test on homelab server
|
||||||
|
411: - Verify checks
|
||||||
|
412: - Verify database connection
|
||||||
|
413: - Test restart behavior
|
||||||
|
```
|
||||||
|
|
||||||
|
## Deployment Decisions (User Confirmed)
|
||||||
|
|
||||||
|
### 1. MongoDB Deployment
|
||||||
|
✅ **New MongoDB instance in docker-compose**
|
||||||
|
- MongoDB will be spun up as part of docker-compose.yml
|
||||||
|
- Volume mounts for data persistence
|
||||||
|
- Standard port 27017 for admin tool access
|
||||||
|
|
||||||
|
### 2. Reverse Proxy
|
||||||
|
✅ **Using reverse proxy for TLS termination**
|
||||||
|
- Backend handles HTTP only
|
||||||
|
- TLS/HTTPS handled by reverse proxy (Nginx/Traefik/Caddy)
|
||||||
|
- CORS configuration needed for allowed origins
|
||||||
|
|
||||||
|
### 3. Development Workflow
|
||||||
|
✅ **Hot reload for local development**
|
||||||
|
- Use `cargo-watch` for auto-rebuild on file changes
|
||||||
|
- Separate docker-compose.dev.yml for development
|
||||||
|
- Production build without hot reload
|
||||||
|
|
||||||
|
### 4. Resource Limits
|
||||||
|
✅ **Homelab resource constraints**
|
||||||
|
- CPU: 1000m (1 CPU core limit)
|
||||||
|
- Memory: 1000Mi (1GB RAM limit)
|
||||||
|
- Configure in docker-compose.yml
|
||||||
|
- Configure in Kubernetes Deployment for future
|
||||||
|
|
||||||
|
### 5. Repository & CI/CD
|
||||||
|
✅ **Forgejo repository**
|
||||||
|
- Git hosting: Forgejo (self-hosted GitHub-compatible)
|
||||||
|
- CI/CD: Forgejo Actions (GitHub Actions compatible)
|
||||||
|
- Single repository for backend, mobile, web
|
||||||
|
|
||||||
|
## Updated Monorepo Structure
|
||||||
|
|
||||||
|
```
|
||||||
|
normogen/ # Root repository
|
||||||
|
├── backend/ # Rust backend
|
||||||
|
│ ├── src/ # Source code
|
||||||
|
│ │ ├── main.rs
|
||||||
|
│ │ ├── auth/
|
||||||
|
│ │ ├── api/
|
||||||
|
│ │ ├── db/
|
||||||
|
│ │ └── config/
|
||||||
|
│ ├── docker/
|
||||||
|
│ │ └── Dockerfile # Multi-stage build
|
||||||
|
│ ├── Cargo.toml
|
||||||
|
│ ├── Cargo.lock
|
||||||
|
│ ├── docker-compose.yml # Homelab deployment
|
||||||
|
│ ├── docker-compose.dev.yml # Development with hot reload
|
||||||
|
│ ├── config/
|
||||||
|
│ │ ├── .env.example
|
||||||
|
│ │ └── defaults.env
|
||||||
|
│ └── k8s/ # Future Kubernetes manifests
|
||||||
|
│ ├── base/
|
||||||
|
│ └── overlays/
|
||||||
|
│
|
||||||
|
├── mobile/ # React Native (iOS + Android)
|
||||||
|
│ ├── src/ # Source code
|
||||||
|
│ │ ├── components/
|
||||||
|
│ │ ├── screens/
|
||||||
|
│ │ ├── navigation/
|
||||||
|
│ │ ├── store/
|
||||||
|
│ │ ├── services/
|
||||||
|
│ │ └── utils/
|
||||||
|
│ ├── package.json
|
||||||
|
│ ├── tsconfig.json
|
||||||
|
│ ├── App.tsx
|
||||||
|
│ └── android/
|
||||||
|
│ └── ios/
|
||||||
|
│
|
||||||
|
├── web/ # React web app
|
||||||
|
│ ├── src/ # Source code
|
||||||
|
│ │ ├── components/
|
||||||
|
│ │ ├── pages/
|
||||||
|
│ │ ├── store/
|
||||||
|
│ │ ├── services/
|
||||||
|
│ │ └── utils/
|
||||||
|
│ ├── package.json
|
||||||
|
│ ├── tsconfig.json
|
||||||
|
│ └── index.html
|
||||||
|
│
|
||||||
|
├── shared/ # Shared TypeScript code
|
||||||
|
│ ├── src/
|
||||||
|
│ │ ├── types/ # Shared types
|
||||||
|
│ │ ├── validation/ # Zod schemas
|
||||||
|
│ │ ├── encryption/ # Encryption utilities
|
||||||
|
│ │ └── api/ # API client
|
||||||
|
│ └── package.json
|
||||||
|
│
|
||||||
|
├── thoughts/ # Research & design docs
|
||||||
|
│ └── research/
|
||||||
|
│
|
||||||
|
├── .gitignore # Root gitignore
|
||||||
|
├── README.md # Root README
|
||||||
|
└── docker-compose.root.yml # Optional: Run all services
|
||||||
|
```
|
||||||
|
|
||||||
|
### Updated Docker Compose with Resource Limits
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
# docker-compose.yml (production)
|
||||||
|
version: '3.8'
|
||||||
|
|
||||||
|
services:
|
||||||
|
backend:
|
||||||
|
build:
|
||||||
|
context: .
|
||||||
|
dockerfile: docker/Dockerfile
|
||||||
|
container_name: normogen-backend
|
||||||
|
ports:
|
||||||
|
- "6000:8000"
|
||||||
|
environment:
|
||||||
|
- RUST_LOG=${RUST_LOG:-info}
|
||||||
|
- SERVER_PORT=8000
|
||||||
|
- MONGODB_URI=mongodb://mongodb:27017/normogen
|
||||||
|
- MONGODB_DATABASE=${MONGODB_DATABASE:-normogen}
|
||||||
|
- JWT_SECRET=${JWT_SECRET}
|
||||||
|
- JWT_ACCESS_TOKEN_EXPIRY_MINUTES=${JWT_ACCESS_TOKEN_EXPIRY_MINUTES:-15}
|
||||||
|
- JWT_REFRESH_TOKEN_EXPIRY_DAYS=${JWT_REFRESH_TOKEN_EXPIRY_DAYS:-30}
|
||||||
|
env_file:
|
||||||
|
- config/.env
|
||||||
|
depends_on:
|
||||||
|
mongodb:
|
||||||
|
condition: service_healthy
|
||||||
|
networks:
|
||||||
|
- normogen-network
|
||||||
|
restart: unless-stopped
|
||||||
|
deploy:
|
||||||
|
resources:
|
||||||
|
limits:
|
||||||
|
cpus: '1.0' # 1 CPU core
|
||||||
|
memory: 1000M # 1GB RAM
|
||||||
|
reservations:
|
||||||
|
cpus: '0.25'
|
||||||
|
memory: 256M
|
||||||
|
check:
|
||||||
|
test: ["CMD", "wget", "--no-verbose", "--tries=1", "--spider", "http://localhost:8000/health"]
|
||||||
|
interval: 30s
|
||||||
|
timeout: 10s
|
||||||
|
retries: 3
|
||||||
|
start_period: 40s
|
||||||
|
|
||||||
|
mongodb:
|
||||||
|
image: mongo:6.0
|
||||||
|
container_name: normogen-mongodb
|
||||||
|
ports:
|
||||||
|
- "27017:27017"
|
||||||
|
environment:
|
||||||
|
- MONGO_INITDB_DATABASE=${MONGO_DATABASE:-normogen}
|
||||||
|
volumes:
|
||||||
|
- mongodb_data:/data/db
|
||||||
|
- mongodb_config:/data/configdb
|
||||||
|
networks:
|
||||||
|
- normogen-network
|
||||||
|
restart: unless-stopped
|
||||||
|
deploy:
|
||||||
|
resources:
|
||||||
|
limits:
|
||||||
|
cpus: '0.5'
|
||||||
|
memory: 512M
|
||||||
|
reservations:
|
||||||
|
cpus: '0.25'
|
||||||
|
memory: 128M
|
||||||
|
check:
|
||||||
|
test: ["CMD", "mongosh", "--eval", "db.adminCommand('ping')"]
|
||||||
|
interval: 10s
|
||||||
|
timeout: 5s
|
||||||
|
retries: 5
|
||||||
|
start_period: 10s
|
||||||
|
|
||||||
|
volumes:
|
||||||
|
mongodb_data:
|
||||||
|
driver: local
|
||||||
|
mongodb_config:
|
||||||
|
driver: local
|
||||||
|
|
||||||
|
networks:
|
||||||
|
normogen-network:
|
||||||
|
driver: bridge
|
||||||
|
```
|
||||||
|
|
||||||
|
### Development Docker Compose (Hot Reload)
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
# docker-compose.dev.yml (development)
|
||||||
|
version: '3.8'
|
||||||
|
|
||||||
|
services:
|
||||||
|
backend:
|
||||||
|
build:
|
||||||
|
context: .
|
||||||
|
dockerfile: docker/Dockerfile.dev
|
||||||
|
container_name: normogen-backend-dev
|
||||||
|
ports:
|
||||||
|
- "6000:8000"
|
||||||
|
volumes:
|
||||||
|
- ./src:/app/src # Hot reload: Mount source code
|
||||||
|
- ./Cargo.toml:/app/Cargo.toml
|
||||||
|
environment:
|
||||||
|
- RUST_LOG=debug
|
||||||
|
- SERVER_PORT=8000
|
||||||
|
- MONGODB_URI=mongodb://mongodb:27017/normogen
|
||||||
|
- MONGODB_DATABASE=normogen_dev
|
||||||
|
- JWT_SECRET=dev-secret-do-not-use-in-production
|
||||||
|
- CARGO_WATCH=1 # Enable hot reload
|
||||||
|
depends_on:
|
||||||
|
mongodb:
|
||||||
|
condition: service_healthy
|
||||||
|
networks:
|
||||||
|
- normogen-network
|
||||||
|
restart: unless-stopped
|
||||||
|
|
||||||
|
mongodb:
|
||||||
|
image: mongo:6.0
|
||||||
|
container_name: normogen-mongodb-dev
|
||||||
|
ports:
|
||||||
|
- "27017:27017"
|
||||||
|
environment:
|
||||||
|
- MONGO_INITDB_DATABASE=normogen_dev
|
||||||
|
volumes:
|
||||||
|
- mongodb_dev_data:/data/db
|
||||||
|
networks:
|
||||||
|
- normogen-network
|
||||||
|
check:
|
||||||
|
test: ["CMD", "mongosh", "--eval", "db.adminCommand('ping')"]
|
||||||
|
interval: 10s
|
||||||
|
timeout: 5s
|
||||||
|
retries: 5
|
||||||
|
|
||||||
|
volumes:
|
||||||
|
mongodb_dev_data:
|
||||||
|
driver: local
|
||||||
|
|
||||||
|
networks:
|
||||||
|
normogen-network:
|
||||||
|
driver: bridge
|
||||||
|
```
|
||||||
|
|
||||||
|
### Development Dockerfile (with cargo-watch)
|
||||||
|
|
||||||
|
```dockerfile
|
||||||
|
# docker/Dockerfile.dev
|
||||||
|
|
||||||
|
FROM rust:1.75-alpine
|
||||||
|
WORKDIR /app
|
||||||
|
|
||||||
|
# Install runtime and build dependencies
|
||||||
|
RUN apk add --no-cache \
|
||||||
|
musl-dev \
|
||||||
|
pkgconf \
|
||||||
|
openssl-dev \
|
||||||
|
curl \
|
||||||
|
wget \
|
||||||
|
git
|
||||||
|
|
||||||
|
# Install cargo-watch for hot reload
|
||||||
|
RUN cargo install cargo-watch
|
||||||
|
|
||||||
|
# Copy manifests
|
||||||
|
COPY Cargo.toml Cargo.lock ./
|
||||||
|
|
||||||
|
# Create dummy main.rs to build dependencies
|
||||||
|
RUN mkdir src && echo "fn main() {}" > src/main.rs
|
||||||
|
RUN cargo build && rm -rf src
|
||||||
|
|
||||||
|
# Copy source code (will be mounted as volume in dev)
|
||||||
|
COPY src ./src
|
||||||
|
|
||||||
|
# Expose port
|
||||||
|
EXPOSE 8000
|
||||||
|
|
||||||
|
# Run with hot reload
|
||||||
|
CMD ["cargo-watch", "-x", "run"]
|
||||||
|
```
|
||||||
|
|
||||||
|
### Forgejo CI/CD (Example)
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
# .forgejo/workflows/backend-build.yml
|
||||||
|
name: Build and Test Backend
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches: [main, develop]
|
||||||
|
pull_request:
|
||||||
|
branches: [main, develop]
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
build:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v3
|
||||||
|
|
||||||
|
- name: Install Rust
|
||||||
|
uses: actions-rust-lang/setup-rust-toolchain@v1
|
||||||
|
|
||||||
|
- name: Cache cargo registry
|
||||||
|
uses: actions/cache@v3
|
||||||
|
with:
|
||||||
|
path: ~/.cargo/registry
|
||||||
|
key: ${{ runner.os }}-cargo-registry-${{ hashFiles('**/Cargo.lock') }}
|
||||||
|
|
||||||
|
- name: Build backend
|
||||||
|
working-directory: ./backend
|
||||||
|
run: cargo build --verbose
|
||||||
|
|
||||||
|
- name: Run tests
|
||||||
|
working-directory: ./backend
|
||||||
|
run: cargo test --verbose
|
||||||
|
|
||||||
|
- name: Build Docker image
|
||||||
|
working-directory: ./backend
|
||||||
|
run: docker build -f docker/Dockerfile -t normogen-backend:${{ github.sha }} .
|
||||||
|
|
||||||
|
deploy-homelab:
|
||||||
|
needs: build
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
if: github.ref == 'refs/heads/main'
|
||||||
|
steps:
|
||||||
|
- name: Deploy to homelab
|
||||||
|
run: |
|
||||||
|
echo "Deploy to homelab server"
|
||||||
|
# Add deployment script here
|
||||||
|
```
|
||||||
|
|
||||||
|
### CORS Configuration (for Reverse Proxy)
|
||||||
|
|
||||||
|
```rust
|
||||||
|
// src/config/cors.rs
|
||||||
|
use tower_http::cors::{CorsLayer, Any};
|
||||||
|
use axum::http::{HeaderValue, Method};
|
||||||
|
|
||||||
|
pub fn create_cors_layer(allowed_origins: &str) -> CorsLayer {
|
||||||
|
let origins: Vec<&str> = allowed_origins.split(',').map(|s| s.trim()).collect();
|
||||||
|
|
||||||
|
CorsLayer::new()
|
||||||
|
.allow_origin(origins.into_iter().map(|s| {
|
||||||
|
s.parse::<HeaderValue>().unwrap()
|
||||||
|
}).collect::<Vec<_>>())
|
||||||
|
.allow_methods([Method::GET, Method::POST, Method::PUT, Method::PATCH, Method::DELETE, Method::OPTIONS])
|
||||||
|
.allow_headers(Any)
|
||||||
|
.allow_credentials(true)
|
||||||
|
.max_age(3600)
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## Updated Deployment Checklist
|
||||||
|
|
||||||
|
### Initial Setup
|
||||||
|
- [ ] Clone repository from Forgejo
|
||||||
|
- [ ] Copy `backend/config/.env.example` to `backend/config/.env`
|
||||||
|
- [ ] Configure environment variables
|
||||||
|
- [ ] Generate JWT secret: `openssl rand -base64 32`
|
||||||
|
- [ ] Set resource limits in docker-compose.yml
|
||||||
|
|
||||||
|
### Development Setup
|
||||||
|
- [ ] Run development: `docker compose -f docker-compose.dev.yml up -d`
|
||||||
|
- [ ] Check logs: `docker compose -f docker-compose.dev.yml logs -f backend`
|
||||||
|
- [ ] Test hot reload: Make changes to src/, verify auto-rebuild
|
||||||
|
|
||||||
|
### Production Deployment
|
||||||
|
- [ ] Run production: `docker compose up -d`
|
||||||
|
- [ ] Check logs: `docker compose logs -f backend`
|
||||||
|
- [ ] Verify resource limits: `docker stats`
|
||||||
|
- [ ] Configure reverse proxy (Nginx/Traefik/Caddy)
|
||||||
|
- [ ] Configure reverse proxy CORS headers
|
||||||
|
- [ ] Test API through reverse proxy
|
||||||
|
|
||||||
312
thoughts/research/2026-02-14-monorepo-structure.md
Normal file
312
thoughts/research/2026-02-14-monorepo-structure.md
Normal file
|
|
@ -0,0 +1,312 @@
|
||||||
|
# Monorepo Structure
|
||||||
|
|
||||||
|
## Repository Layout
|
||||||
|
|
||||||
|
```
|
||||||
|
normogen/ # Root Forgejo repository
|
||||||
|
├── backend/ # Rust backend (Axum + MongoDB)
|
||||||
|
│ ├── src/ # Source code
|
||||||
|
│ │ ├── main.rs # Entry point
|
||||||
|
│ │ ├── auth/ # Authentication
|
||||||
|
│ │ │ ├── mod.rs
|
||||||
|
│ │ │ ├── jwt_service.rs
|
||||||
|
│ │ │ ├── claims.rs
|
||||||
|
│ │ │ └── middleware.rs
|
||||||
|
│ │ ├── api/ # API endpoints
|
||||||
|
│ │ │ ├── mod.rs
|
||||||
|
│ │ │ ├── users.rs
|
||||||
|
│ │ │ ├── families.rs
|
||||||
|
│ │ │ ├── profiles.rs
|
||||||
|
│ │ │ ├── health_data.rs
|
||||||
|
│ │ │ ├── lab_results.rs
|
||||||
|
│ │ │ ├── medications.rs
|
||||||
|
│ │ │ ├── appointments.rs
|
||||||
|
│ │ │ └── shares.rs
|
||||||
|
│ │ ├── db/ # Database
|
||||||
|
│ │ │ ├── mod.rs
|
||||||
|
│ │ │ ├── mongo.rs
|
||||||
|
│ │ │ ├── models.rs
|
||||||
|
│ │ │ └── repositories.rs
|
||||||
|
│ │ ├── config/ # Configuration
|
||||||
|
│ │ │ ├── mod.rs
|
||||||
|
│ │ │ ├── app.rs
|
||||||
|
│ │ │ ├── jwt.rs
|
||||||
|
│ │ │ ├── mongo.rs
|
||||||
|
│ │ │ └── cors.rs
|
||||||
|
│ │ ├── middleware/ # Middleware
|
||||||
|
│ │ │ ├── mod.rs
|
||||||
|
│ │ │ ├── auth.rs
|
||||||
|
│ │ │ ├── logging.rs
|
||||||
|
│ │ │ └── rate_limit.rs
|
||||||
|
│ │ ├── utils/ # Utilities
|
||||||
|
│ │ │ ├── mod.rs
|
||||||
|
│ │ │ ├── crypto.rs
|
||||||
|
│ │ │ └── validation.rs
|
||||||
|
│ │ └── error.rs # Error types
|
||||||
|
│ ├── docker/
|
||||||
|
│ │ ├── Dockerfile # Production build
|
||||||
|
│ │ └── Dockerfile.dev # Development build
|
||||||
|
│ ├── config/
|
||||||
|
│ │ ├── .env.example # Environment template
|
||||||
|
│ │ └── defaults.env # Default values
|
||||||
|
│ ├── k8s/ # Kubernetes manifests (future)
|
||||||
|
│ │ ├── base/
|
||||||
|
│ │ └── overlays/
|
||||||
|
│ ├── Cargo.toml # Dependencies
|
||||||
|
│ ├── Cargo.lock # Lock file
|
||||||
|
│ ├── docker-compose.yml # Production deployment
|
||||||
|
│ ├── docker-compose.dev.yml # Development deployment
|
||||||
|
│ └── README.md # Backend README
|
||||||
|
│
|
||||||
|
├── mobile/ # React Native (iOS + Android)
|
||||||
|
│ ├── src/ # Source code
|
||||||
|
│ │ ├── components/ # Reusable components
|
||||||
|
│ │ │ ├── common/
|
||||||
|
│ │ │ ├── health/
|
||||||
|
│ │ │ ├── lab/
|
||||||
|
│ │ │ └── medication/
|
||||||
|
│ │ ├── screens/ # Screen components
|
||||||
|
│ │ │ ├── auth/
|
||||||
|
│ │ │ ├── home/
|
||||||
|
│ │ │ ├── family/
|
||||||
|
│ │ │ ├── profile/
|
||||||
|
│ │ │ ├── health/
|
||||||
|
│ │ │ ├── lab/
|
||||||
|
│ │ │ └── settings/
|
||||||
|
│ │ ├── navigation/ # Navigation config
|
||||||
|
│ │ │ ├── AppNavigator.tsx
|
||||||
|
│ │ │ ├── AuthNavigator.tsx
|
||||||
|
│ │ │ └── LinkingConfiguration.tsx
|
||||||
|
│ │ ├── store/ # Redux store
|
||||||
|
│ │ │ ├── slices/
|
||||||
|
│ │ │ │ ├── authSlice.ts
|
||||||
|
│ │ │ │ ├── userSlice.ts
|
||||||
|
│ │ │ │ ├── familySlice.ts
|
||||||
|
│ │ │ │ ├── profileSlice.ts
|
||||||
|
│ │ │ │ └── healthDataSlice.ts
|
||||||
|
│ │ │ └── store.ts
|
||||||
|
│ │ ├── services/ # API services
|
||||||
|
│ │ │ ├── api.ts # Axios client
|
||||||
|
│ │ │ ├── authService.ts
|
||||||
|
│ │ │ ├── userService.ts
|
||||||
|
│ │ │ └── healthDataService.ts
|
||||||
|
│ │ ├── utils/ # Utilities
|
||||||
|
│ │ │ ├── encryption.ts # Client-side encryption
|
||||||
|
│ │ │ ├── validation.ts
|
||||||
|
│ │ │ └── constants.ts
|
||||||
|
│ │ ├── hooks/ # Custom hooks
|
||||||
|
│ │ │ ├── useAuth.ts
|
||||||
|
│ │ │ └── useEncryptedStorage.ts
|
||||||
|
│ │ ├── types/ # TypeScript types
|
||||||
|
│ │ │ └── index.ts
|
||||||
|
│ │ └── assets/ # Images, fonts
|
||||||
|
│ ├── android/ # Android native code
|
||||||
|
│ │ ├── app/
|
||||||
|
│ │ └── build.gradle
|
||||||
|
│ ├── ios/ # iOS native code
|
||||||
|
│ │ ├── Normogen
|
||||||
|
│ │ └── Podfile
|
||||||
|
│ ├── package.json
|
||||||
|
│ ├── tsconfig.json
|
||||||
|
│ ├── App.tsx # Entry component
|
||||||
|
│ ├── README.md
|
||||||
|
│ └── .env.example
|
||||||
|
│
|
||||||
|
├── web/ # React web app
|
||||||
|
│ ├── src/ # Source code
|
||||||
|
│ │ ├── components/ # Reusable components
|
||||||
|
│ │ │ ├── common/
|
||||||
|
│ │ │ ├── health/
|
||||||
|
│ │ │ ├── lab/
|
||||||
|
│ │ │ └── charts/
|
||||||
|
│ │ ├── pages/ # Page components
|
||||||
|
│ │ │ ├── auth/
|
||||||
|
│ │ │ ├── home/
|
||||||
|
│ │ │ ├── family/
|
||||||
|
│ │ │ ├── profile/
|
||||||
|
│ │ │ ├── health/
|
||||||
|
│ │ │ ├── lab/
|
||||||
|
│ │ │ └── settings/
|
||||||
|
│ │ ├── store/ # Redux store (shared with mobile)
|
||||||
|
│ │ │ ├── slices/
|
||||||
|
│ │ │ └── store.ts
|
||||||
|
│ │ ├── services/ # API services (shared with mobile)
|
||||||
|
│ │ │ ├── api.ts
|
||||||
|
│ │ │ └── ...
|
||||||
|
│ │ ├── utils/ # Utilities (shared with mobile)
|
||||||
|
│ │ │ ├── encryption.ts
|
||||||
|
│ │ │ └── ...
|
||||||
|
│ │ ├── hooks/ # Custom hooks
|
||||||
|
│ │ │ └── ...
|
||||||
|
│ │ ├── types/ # TypeScript types (shared)
|
||||||
|
│ │ │ └── index.ts
|
||||||
|
│ │ ├── styles/ # CSS/global styles
|
||||||
|
│ │ │ └── global.css
|
||||||
|
│ │ └── App.tsx
|
||||||
|
│ ├── package.json
|
||||||
|
│ ├── tsconfig.json
|
||||||
|
│ ├── index.html
|
||||||
|
│ ├── vite.config.ts # Vite config
|
||||||
|
│ └── README.md
|
||||||
|
│
|
||||||
|
├── shared/ # Shared TypeScript code
|
||||||
|
│ ├── src/
|
||||||
|
│ │ ├── types/ # Shared type definitions
|
||||||
|
│ │ │ ├── user.ts
|
||||||
|
│ │ │ ├── family.ts
|
||||||
|
│ │ │ ├── profile.ts
|
||||||
|
│ │ │ ├── healthData.ts
|
||||||
|
│ │ │ ├── labResults.ts
|
||||||
|
│ │ │ ├── medications.ts
|
||||||
|
│ │ │ ├── appointments.ts
|
||||||
|
│ │ │ ├── shares.ts
|
||||||
|
│ │ │ └── api.ts
|
||||||
|
│ │ ├── validation/ # Zod schemas
|
||||||
|
│ │ │ ├── user.ts
|
||||||
|
│ │ │ ├── family.ts
|
||||||
|
│ │ │ └── healthData.ts
|
||||||
|
│ │ ├── encryption/ # Encryption utilities
|
||||||
|
│ │ │ ├── crypto.ts
|
||||||
|
│ │ │ └── keyDerivation.ts
|
||||||
|
│ │ ├── api/ # Shared API client
|
||||||
|
│ │ │ ├── client.ts
|
||||||
|
│ │ │ └── endpoints.ts
|
||||||
|
│ │ └── constants/ # Shared constants
|
||||||
|
│ │ ├── routes.ts
|
||||||
|
│ │ └── config.ts
|
||||||
|
│ ├── package.json
|
||||||
|
│ ├── tsconfig.json
|
||||||
|
│ └── README.md
|
||||||
|
│
|
||||||
|
├── thoughts/ # Research & design docs
|
||||||
|
│ ├── research/
|
||||||
|
│ │ ├── 2026-02-14-rust-framework-comparison.md
|
||||||
|
│ │ ├── 2026-02-14-rust-framework-performance-research.md
|
||||||
|
│ │ ├── 2026-02-14-performance-findings.md
|
||||||
|
│ │ ├── 2026-02-14-research-summary.md
|
||||||
|
│ │ ├── 2026-02-14-frontend-mobile-research.md
|
||||||
|
│ │ ├── 2026-02-14-frontend-decision-summary.md
|
||||||
|
│ │ ├── 2026-02-14-state-management-research.md
|
||||||
|
│ │ ├── 2026-02-14-state-management-decision.md
|
||||||
|
│ │ ├── 2026-02-14-jwt-authentication-research.md
|
||||||
|
│ │ ├── 2026-02-14-jwt-authentication-decision.md
|
||||||
|
│ │ ├── 2026-02-14-mongodb-schema-design-research.md
|
||||||
|
│ │ ├── 2026-02-14-mongodb-schema-decision.md
|
||||||
|
│ │ ├── 2026-02-14-backend-deployment-constraints.md
|
||||||
|
│ │ └── 2026-02-14-monorepo-structure.md
|
||||||
|
│ └── research/
|
||||||
|
│
|
||||||
|
├── .gitignore # Root gitignore
|
||||||
|
├── README.md # Root README
|
||||||
|
├── docker-compose.root.yml # Run all services (optional)
|
||||||
|
└── .forgejo/ # Forgejo CI/CD workflows
|
||||||
|
└── workflows/
|
||||||
|
├── backend-build.yml
|
||||||
|
├── mobile-build.yml
|
||||||
|
└── web-build.yml
|
||||||
|
```
|
||||||
|
|
||||||
|
## Directory Creation Commands
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Create root directories
|
||||||
|
mkdir -p backend/{src/{auth,api,db,config,middleware,utils},docker,config,k8s/base,k8s/overlays/homelab,k8s/overlays/production}
|
||||||
|
mkdir -p mobile/{src/{components/{common,health,lab,medication},screens/{auth,home,family,profile,health,lab,settings},navigation,store/slices,services,utils,hooks,types,assets},android,ios}
|
||||||
|
mkdir -p web/{src/{components/{common,health,lab,charts},pages/{auth,home,family,profile,health,lab,settings},store/slices,services,utils,hooks,types,styles}}
|
||||||
|
mkdir -p shared/src/{types,validation,encryption,api,constants}
|
||||||
|
mkdir -p thoughts/research
|
||||||
|
mkdir -p .forgejo/workflows
|
||||||
|
|
||||||
|
# Create placeholder files
|
||||||
|
touch backend/src/{main.rs,auth/mod.rs,api/mod.rs,db/mod.rs,config/mod.rs,middleware/mod.rs,utils/mod.rs,error.rs}
|
||||||
|
touch mobile/src/{App.tsx,navigation/AppNavigator.tsx,store/store.ts,services/api.ts,utils/encryption.ts}
|
||||||
|
touch web/src/{App.tsx,store/store.ts,services/api.ts,utils/encryption.ts}
|
||||||
|
touch shared/src/{types/index.ts,validation/index.ts,encryption/crypto.ts,api/client.ts}
|
||||||
|
```
|
||||||
|
|
||||||
|
## Git Strategy
|
||||||
|
|
||||||
|
### Branch Strategy
|
||||||
|
- `main`: Production releases
|
||||||
|
- `develop`: Development integration
|
||||||
|
- `feature/backend-*`: Backend features
|
||||||
|
- `feature/mobile-*`: Mobile features
|
||||||
|
- `feature/web-*`: Web features
|
||||||
|
- `feature/shared-*`: Shared code features
|
||||||
|
|
||||||
|
### Commit Message Format
|
||||||
|
```
|
||||||
|
<type>(<scope>): <subject>
|
||||||
|
|
||||||
|
<body>
|
||||||
|
|
||||||
|
<footer>
|
||||||
|
```
|
||||||
|
|
||||||
|
Types: feat, fix, docs, style, refactor, test, chore
|
||||||
|
|
||||||
|
Scopes: backend, mobile, web, shared, ci/cd
|
||||||
|
|
||||||
|
Examples:
|
||||||
|
- `feat(backend): Implement JWT authentication with refresh tokens`
|
||||||
|
- `fix(mobile): Resolve encryption key storage issue`
|
||||||
|
- `docs(shared): Update API type definitions`
|
||||||
|
- `chore(ci/cd): Add Forgejo workflow for backend builds`
|
||||||
|
|
||||||
|
## Shared Code Management
|
||||||
|
|
||||||
|
### TypeScript Package
|
||||||
|
The `shared/` directory contains TypeScript code shared between mobile and web:
|
||||||
|
- Type definitions (API models)
|
||||||
|
- Validation schemas (Zod)
|
||||||
|
- Encryption utilities
|
||||||
|
- API client
|
||||||
|
- Constants
|
||||||
|
|
||||||
|
### Usage in Mobile/Web
|
||||||
|
```json
|
||||||
|
// mobile/package.json and web/package.json
|
||||||
|
{
|
||||||
|
"dependencies": {
|
||||||
|
"shared": "file:../shared"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### Watch Mode for Development
|
||||||
|
```bash
|
||||||
|
# In shared/ directory
|
||||||
|
npm run watch # Watch and rebuild on changes
|
||||||
|
|
||||||
|
# In mobile/ and web/ directories
|
||||||
|
# Changes to shared/ are automatically picked up
|
||||||
|
```
|
||||||
|
|
||||||
|
## Next Steps
|
||||||
|
|
||||||
|
1. **Initialize Monorepo Structure**
|
||||||
|
- Create all directories
|
||||||
|
- Create placeholder files
|
||||||
|
- Update root .gitignore
|
||||||
|
|
||||||
|
2. **Backend Initialization**
|
||||||
|
- Initialize Rust project (backend/)
|
||||||
|
- Setup Cargo.toml
|
||||||
|
- Create docker-compose files
|
||||||
|
- Create Dockerfiles
|
||||||
|
|
||||||
|
3. **Shared Code Setup**
|
||||||
|
- Initialize TypeScript project (shared/)
|
||||||
|
- Setup type definitions
|
||||||
|
- Setup Zod validation schemas
|
||||||
|
- Setup encryption utilities
|
||||||
|
|
||||||
|
4. **Mobile Setup** (Phase 3)
|
||||||
|
- Initialize React Native project
|
||||||
|
- Setup Redux Toolkit
|
||||||
|
- Setup navigation
|
||||||
|
|
||||||
|
5. **Web Setup** (Phase 3)
|
||||||
|
- Initialize React project
|
||||||
|
- Setup Redux Toolkit
|
||||||
|
- Setup routing
|
||||||
Loading…
Add table
Add a link
Reference in a new issue