# Data models Source: https://docs.feedaura.in/engineering/architecture/data-models Core entities, their key fields, relationships, and where they live. This page documents the primary domain entities. For schema definitions, see the migration files in the Core API repo. ## Core entities ### User Represents an authenticated person. One user can belong to multiple organizations. | Field | Type | Description | | --------------- | --------- | ---------------------- | | `id` | UUID | Primary key | | `email` | string | Unique, used for login | | `created_at` | timestamp | Account creation time | | `last_login_at` | timestamp | Last successful auth | ### Organization A company or team account. The primary billing and access control boundary. | Field | Type | Description | | ---------- | --------- | --------------------------- | | `id` | UUID | Primary key | | `name` | string | Display name | | `plan` | enum | `free`, `pro`, `enterprise` | | `owner_id` | FK → User | Billing owner | ### Membership Junction table linking users to organizations with a role. | Field | Type | Description | | ----------- | ----------------- | -------------------------- | | `user_id` | FK → User | | | `org_id` | FK → Organization | | | `role` | enum | `owner`, `admin`, `member` | | `joined_at` | timestamp | | ## Relationships ```mermaid theme={null} graph LR User --- Membership Organization --- Membership User --- Organization ``` A user can be a member of many organizations. An organization can have many members. The `Membership` table holds the role for each pair. ## Data storage | Data type | Storage | Notes | | --------------- | -------------------------- | ------------------------------- | | Relational data | Postgres | Primary store, via Core API | | Sessions | Redis | TTL-based, auto-expire | | File uploads | S3-compatible object store | Referenced by URL in Postgres | | Search index | \[Search service] | Synced from Postgres via worker | ## Sensitive fields The following fields are encrypted at rest and must never appear in logs: * `User.password_hash` * Payment method tokens (stored in your payment processor, referenced by ID only) * Any field containing PII in audit logs If you're adding a new field that contains PII or credentials, flag it in your PR for security review. # Architecture Source: https://docs.feedaura.in/engineering/architecture/index Overview of our services and how they fit together. This section documents the high-level architecture of our systems. For detailed runbooks on specific services, check the service's own README or ask in `#eng`. The main services, what they do, and how they communicate. Core entities, their relationships, and where they live. # Services overview Source: https://docs.feedaura.in/engineering/architecture/services-overview The main services that make up our platform, what each one does, and how they communicate. This page gives a high-level map of our backend services. Each service has its own README with deeper documentation. ## Service map ```mermaid theme={null} graph TD Client([Client]) --> GW[API Gateway] GW --> Auth[Auth Service] GW --> Core[Core API] GW --> Worker[Worker Service] Core --> DB[(Database\nprimary store)] Core --> Cache[(Cache\nin-memory)] Worker --> DB Worker --> Cache Core -->|publishes jobs| Queue[[Job Queue]] Worker -->|consumes jobs| Queue ``` ## Services ### API Gateway The public-facing entry point. Handles routing, rate limiting, and authentication checks before forwarding requests to downstream services. Deployed on \[Platform]. **Repo:** `api-gateway` ### Auth Service Manages user identity, sessions, and permissions. Integrates with your identity provider for SSO. All authentication decisions are delegated here — other services call Auth to validate tokens. **Repo:** `auth-service` ### Core API The main application backend. Handles business logic for the primary product domain. Owns the primary database. **Repo:** `core-api` ### Worker Service Processes background jobs: email delivery, async data processing, scheduled tasks, and webhook delivery. Consumes from the job queue. **Repo:** `worker` ## Communication patterns * **Synchronous:** Services communicate via internal HTTP APIs. Auth headers are passed through and validated at each service boundary. * **Asynchronous:** Workers consume from the job queue. The Core API publishes jobs; workers process them independently. * **Events:** Significant domain events (user created, subscription changed) are published to the event bus for downstream consumers. ## Environments | Environment | Purpose | Access | | ----------- | --------------------------- | ---------------- | | Local | Development | All engineers | | Staging | Pre-production verification | All engineers | | Production | Live traffic | Deploy tool only | # Deployment Source: https://docs.feedaura.in/engineering/deployment How code goes from a merged PR to production, and how to roll back when something goes wrong. We use a trunk-based deployment model. Merging to `main` triggers a staging deploy automatically; production deploys are triggered manually after verification. ## Flow overview ``` feature branch → PR review → merge to main → auto-deploy to staging → manual promote to production ``` ## Deploying to staging Every merge to `main` triggers a staging deployment automatically via CI. You don't need to do anything. Check the `#deploys` Slack channel for status notifications. Staging deployments take approximately 5–10 minutes. If a deploy fails, CI will post the error in `#deploys` with a link to the failed run. ## Promoting to production Once a change is verified in staging: 1. Go to the deploy tool (link in `#deploys` channel description). 2. Select the staging build you want to promote. 3. Click **Promote to production**. 4. Monitor the `#deploys` channel for confirmation or errors. Production deploys require at least one engineer who didn't author the change to click promote. This is a soft guard — use judgment in an emergency. ## Feature flags Most new features are deployed behind a feature flag to decouple deploy from release. Flags are managed in \[Flag Tool Name]. Ask your tech lead about the flag naming convention and cleanup process. ## Rollbacks If a production deploy causes an incident: 1. Use the deploy tool to roll back to the previous production build immediately. 2. Don't wait to diagnose — roll back first, investigate after. 3. File an [incident](/engineering/incident-response) and start a postmortem if users were affected. Rolling back takes about 2 minutes. It's safe and reversible — do it early. ## Database migrations Migrations run automatically as part of the deploy pipeline. Backward-incompatible migrations require a multi-phase deploy — ask in `#eng` before merging if your migration drops a column or changes a type. ## Deploy freeze windows We freeze production deploys during major events or the last business day before a holiday. The `#deploys` channel will pin a message when a freeze is active. # Developer setup Source: https://docs.feedaura.in/engineering/dev-setup Get your local environment running from a fresh machine in under an hour. This guide assumes a fresh macOS machine with your company laptop already enrolled in MDM. For Windows, see the Windows setup note at the bottom. ## Prerequisites Before you start, make sure you have: * Company laptop with MDM enrolled — see [laptop setup](/onboarding/tools/laptop-setup) * VPN connected — see [VPN setup](/onboarding/tools/vpn-setup) * Git repository access — see [account access](/onboarding/tools/account-access) ## Step 1: Install core tooling Run the bootstrap script — your tech lead will share the link on your first day: ```bash theme={null} /bin/bash -c "$(curl -fsSL https://setup.yourcompany.com/bootstrap.sh)" ``` If you'd rather install manually, the script installs: a package manager, git, your language runtimes, Docker, and your IDE. ## Step 2: Clone the main repository ```bash theme={null} mkdir ~/code && cd ~/code git clone git@git.yourcompany.com:your-repo.git ``` If `git clone` fails with a permission error, your SSH key isn't authorized. Ask your tech lead to check your access. ## Step 3: Set up environment variables Each repo has a `.env.example` in the root. Copy it: ```bash theme={null} cp .env.example .env.local ``` Fill in the required values — ask your tech lead or check the `#eng-setup` Slack channel for development secrets. Do not commit `.env.local`. ## Step 4: Install dependencies and run locally ```bash theme={null} cd your-repo npm install npm run dev ``` The app should be running at `http://localhost:3000`. If you hit errors, check the repo's own `README.md` for service-specific requirements (databases, queues, etc.). ## Step 5: Verify your setup Run the test suite to confirm everything is wired up: ```bash theme={null} npm test ``` All tests should pass on a fresh clone. If they don't, post in `#eng-setup` with the error output before debugging solo. ## Windows We don't officially support Windows for local development. WSL2 works for most engineers, but you'll need to adapt some steps. Check with your tech lead before your start date if you prefer Windows. ## Getting help Post in `#eng-setup` on Slack. Include your OS version, the command you ran, and the full error output. # Incident response Source: https://docs.feedaura.in/engineering/incident-response/index How we detect, respond to, and learn from production incidents. When something breaks in production, the goal is to restore service as quickly as possible — then understand why. ## Severity levels | Level | Description | Response target | | ----- | --------------------------------------------- | -------------------- | | SEV-1 | Production down or data loss | Immediate, all hands | | SEV-2 | Significant degradation, major feature broken | Within 30 minutes | | SEV-3 | Minor degradation, workaround available | Within 2 hours | | SEV-4 | Cosmetic or low-impact issue | Next business day | ## Responding to an alert 1. **Acknowledge** the alert in your alerting tool to signal you're on it. 2. **Assess severity** — is this SEV-1/2 or lower? 3. **Open a war room** — for SEV-1/2, create a Slack thread in `#incidents` and invite your on-call partner. 4. **Mitigate first** — roll back, disable a feature flag, or scale up before diagnosing root cause. 5. **Communicate** — post updates to `#incidents` every 15 minutes until resolved. 6. **Resolve and document** — mark the incident resolved and file a postmortem for SEV-1/2. Rotation schedule, escalation paths, and what to do when you're paged. How to write a blameless postmortem and drive follow-through. # On-call expectations Source: https://docs.feedaura.in/engineering/incident-response/on-call How the on-call rotation works, what's expected of you, and how to escalate. On-call responsibility rotates weekly among engineers on each team. Being on-call means you're the first responder for production alerts during your shift. ## Rotation schedule Check your team's on-call schedule in NightWatch. Schedules are set four weeks in advance. If you need to swap a shift, arrange it directly with a teammate and update the schedule — don't just not show up. New engineers join the rotation after 60 days. Your first few on-call weeks are shadowed — you respond, but a senior engineer is on secondary in case you need backup. ## Before your shift * Confirm your phone number is correct in the alerting tool. * Check `#deploys` for any recent changes that might be fragile. * Review any open SEV-3 issues that could escalate. ## During your shift **Availability:** Respond to pages within 5 minutes during business hours, within 15 minutes outside business hours. If you can't respond within that window, escalate to secondary immediately. **For each alert:** 1. Acknowledge the alert to stop re-paging. 2. Triage: is this a real issue or noise? If noise, resolve and file a ticket to fix the alert. 3. If real, follow the [incident response process](/engineering/incident-response). **Keeping notes:** Keep a running Slack thread in `#incidents` even for small issues. It creates a record and helps the next on-call engineer understand what happened. ## Escalation path If you've been investigating for 15 minutes and are stuck: 1. Page the secondary on-call engineer. 2. If still stuck after another 15 minutes, escalate to your engineering manager. Don't wait until you're really stuck. Asking for help quickly is the right call. ## After your shift Hand off any open issues to the next on-call engineer in `#incidents`. Include: what happened, current status, and what to watch for. ## On-call compensation On-call shifts outside of business hours are compensated. See HR or your manager for current rates. # Postmortem process Source: https://docs.feedaura.in/engineering/incident-response/postmortem How to write a blameless postmortem, facilitate the review, and make sure action items land. Postmortems are required for all SEV-1 and SEV-2 incidents, and optional for recurring SEV-3 patterns. The goal is learning, not blame. ## Blameless means Blameless means we focus on what failed in the system — processes, tooling, alerting, communication — not on who made a mistake. Engineers make good decisions with the information available at the time. The postmortem identifies where the system let them down. ## Timeline | Timing | Action | | ----------------------------- | ------------------------------------------------------- | | Within 24 hours of resolution | Create the postmortem doc from the template | | Within 48 hours | Draft the timeline and contributing factors | | Within 5 business days | Hold the postmortem review meeting | | Within 2 weeks | Action items assigned and tracked in your issue tracker | ## Postmortem template Create a new doc in your wiki using the Postmortem template. Fill in: 1. **Incident summary** — one paragraph: what happened, when, and what the impact was. 2. **Timeline** — chronological log of events (use UTC). Include when the issue started, when it was detected, key actions taken, and when it was resolved. 3. **Root cause** — what was the underlying cause? Use "5 Whys" if helpful. 4. **Contributing factors** — what else made this worse or harder to detect? 5. **Impact** — number of users affected, duration, data involved. 6. **What went well** — things that helped during response. 7. **Action items** — concrete, assigned, with due dates. At least one per significant contributing factor. ## The review meeting Keep it to 30–45 minutes. The incident owner facilitates. Everyone who was involved should attend; others are welcome. Agenda: 1. Walk through the timeline (10 min) 2. Discuss root cause and contributing factors (10 min) 3. Review and assign action items (15 min) Don't re-hash decisions made during the incident. Focus on what to do differently next time. ## Action items Action items without owners don't get done. Every item needs: * A clear description of what "done" looks like * A single owner (not a team) * A due date Track them in your issue tracker. The engineering manager reviews open postmortem action items in the weekly team meeting. # Engineering Source: https://docs.feedaura.in/engineering/index Development setup, deployment processes, incident response, and architecture documentation. This section covers the technical foundations of how we build and operate our systems. ## Get started Get your local environment running from a fresh machine. ## Reference How code goes from a merged PR to production. On-call expectations, escalation paths, and postmortem process. Services overview and data models. # React Application Deployment on AWS EC2 with Nginx Source: https://docs.feedaura.in/frameworks/react/react-ec2-deployment Step-by-step guide to deploying a React application on an AWS EC2 instance behind Nginx, with a custom subdomain, HTTPS, and production hardening. ## Architecture ```text theme={null} User Browser ↓ react.vnta.agency ↓ DNS Record (A Record) ↓ AWS EC2 Public IP ↓ Nginx Web Server ↓ React Build Files ``` ## 1. Launch EC2 instance **Purpose:** EC2 is the Linux server that hosts the React application. **Configuration:** * OS: Ubuntu 24.04 LTS * Instance type: `t3.micro` (learning / small projects) * Key pair: `.pem` file * Public IP enabled ## 2. Configure security group Security Groups act as a firewall for the EC2 instance. **Inbound rules:** | Type | Port | Purpose | | ----- | ---- | ---------------------- | | SSH | 22 | Remote server access | | HTTP | 80 | Website traffic | | HTTPS | 443 | Secure website traffic | **Why:** * Without port `22` — cannot SSH into the server * Without port `80` — website won't load over HTTP * Without port `443` — HTTPS won't work Don't open unnecessary ports (`3000`, `5000`, `8000`, `8080`). Only expose what you actually need. ## 3. Connect to EC2 ```bash theme={null} ssh -i mykey.pem ubuntu@EC2_PUBLIC_IP ``` * `ssh` — Secure Shell. Encrypted connection to the server. * `-i mykey.pem` — use the AWS private key for authentication. * `ubuntu` — default Ubuntu user. * `EC2_PUBLIC_IP` — server address. ## 4. Update the server ```bash theme={null} sudo apt update sudo apt upgrade -y ``` Updates package repository info and installs the latest security patches. ## 5. Install Nginx ```bash theme={null} sudo apt install nginx -y ``` Nginx serves the React build files. ```text theme={null} Linux Server → Nginx → Website Available ``` ## 6. Verify Nginx ```bash theme={null} systemctl status nginx ``` Expected: `active (running)` Open `http://EC2_PUBLIC_IP` — you should see **Welcome to nginx**. ## 7. Enable Nginx on boot ```bash theme={null} sudo systemctl enable nginx ``` Ensures Nginx starts automatically if the server restarts. ## 8. Build the React application On your local machine: ```bash theme={null} npm install npm run build ``` Output: ```text theme={null} build/ ├── index.html ├── static └── assets ``` Browsers can't run `.jsx`, `.tsx`, or Tailwind source directly. The build converts everything into plain HTML, CSS, and JavaScript. ## 9. Create the website directory On EC2: ```bash theme={null} sudo mkdir -p /var/www/react-app ``` By Linux convention, `/var/www` is used for web applications. ## 10. Transfer the React build From your local machine: ```bash theme={null} scp -i mykey.pem -r build/* ubuntu@EC2_PUBLIC_IP:/home/ubuntu/ ``` * `scp` — Secure Copy. Transfers files over SSH. * `-r` — recursive copy. ## 11. Move build files into place SSH back into the server: ```bash theme={null} ssh -i mykey.pem ubuntu@EC2_PUBLIC_IP ``` Move files: ```bash theme={null} sudo cp -r /home/ubuntu/* /var/www/react-app/ ``` Verify: ```bash theme={null} ls /var/www/react-app # index.html static ``` ## 12. Configure Nginx ```bash theme={null} sudo nano /etc/nginx/sites-available/default ``` Replace contents with: ```nginx theme={null} server { listen 80; root /var/www/react-app; index index.html; location / { try_files $uri /index.html; } } ``` ## 13. Understanding the Nginx config **`listen 80;`** — Nginx listens for HTTP traffic on port 80. **`root /var/www/react-app;`** — Location of website files. **`index index.html;`** — Homepage file. **`try_files $uri /index.html;`** — Critical for React Router. Without it, paths like `/about`, `/dashboard`, `/contact` return `404 Not Found`. With it, React handles client-side routing. ## 14. Test the Nginx configuration ```bash theme={null} sudo nginx -t ``` Expected: ```text theme={null} syntax is ok test is successful ``` Always test before reloading — invalid config can crash Nginx. ## 15. Restart Nginx ```bash theme={null} sudo systemctl restart nginx ``` Visit `http://EC2_PUBLIC_IP` — the React app should load. ## 16. Configure the subdomain Target: `react.vnta.agency` In your DNS provider (Vercel DNS, Cloudflare, Namecheap, Route53), create: | Type | Name | Value | | ---- | ----- | --------------- | | A | react | EC2\_PUBLIC\_IP | Example: | Type | Name | Value | | ---- | ----- | ----------- | | A | react | 13.60.19.93 | Result: `react.vnta.agency → 13.60.19.93` ## 17. Verify DNS ```bash theme={null} dig react.vnta.agency # or nslookup react.vnta.agency ``` Expected output should include `13.60.19.93`. ## 18. Configure Nginx for the domain ```bash theme={null} sudo nano /etc/nginx/sites-available/default ``` ```nginx theme={null} server { listen 80; server_name react.vnta.agency; root /var/www/react-app; index index.html; location / { try_files $uri /index.html; } } ``` ## 19. Install an SSL certificate Install Certbot: ```bash theme={null} sudo apt install certbot python3-certbot-nginx -y ``` Generate the certificate: ```bash theme={null} sudo certbot --nginx -d react.vnta.agency ``` Certbot automatically: * Validates domain ownership * Creates the SSL certificate * Updates the Nginx configuration * Enables HTTPS redirect ## 20. Verify HTTPS Visit `https://react.vnta.agency` — you should see the 🔒 secure indicator. ## 21. SSL auto-renewal Check the timer: ```bash theme={null} sudo systemctl status certbot.timer ``` Test renewal: ```bash theme={null} sudo certbot renew --dry-run ``` Let's Encrypt certificates expire every 90 days, so auto-renewal is essential. ## 22. Security headers Add inside the `server` block: ```nginx theme={null} add_header X-Frame-Options SAMEORIGIN always; add_header X-Content-Type-Options nosniff always; add_header Referrer-Policy strict-origin always; ``` * **`X-Frame-Options: SAMEORIGIN`** — prevents clickjacking. * **`X-Content-Type-Options: nosniff`** — prevents MIME type guessing. * **`Referrer-Policy: strict-origin`** — improves privacy. ## 23. Enable compression ```nginx theme={null} gzip on; gzip_types text/plain text/css application/json application/javascript text/xml application/xml; ``` Reduces file sizes (e.g. `1 MB JS → ~200 KB`) for faster loads. ## 24. Browser caching ```nginx theme={null} location /static/ { expires 1y; add_header Cache-Control "public"; } ``` Prevents re-downloading unchanged assets. ## 25. Log monitoring Access logs: ```bash theme={null} sudo tail -f /var/log/nginx/access.log ``` Shows visitors, pages requested, and IP addresses. Error logs: ```bash theme={null} sudo tail -f /var/log/nginx/error.log ``` Shows configuration issues, missing files, and permission problems. ## 26. Common troubleshooting ```bash theme={null} sudo systemctl status nginx sudo systemctl restart nginx ``` ```bash theme={null} sudo nginx -t ``` ```bash theme={null} dig react.vnta.agency ``` Verify the DNS A record. Verify the domain points to the EC2 IP and port 80 is open, then retry: ```bash theme={null} sudo certbot --nginx -d react.vnta.agency ``` ```bash theme={null} ls -la /var/www/react-app sudo chown -R www-data:www-data /var/www/react-app ``` ## Useful daily commands ```bash theme={null} systemctl status nginx systemctl restart nginx systemctl reload nginx nginx -t df -h free -h top htop ss -tulpn journalctl -u nginx tail -f /var/log/nginx/error.log ``` ## Final production checklist * EC2 created * Security groups configured * Nginx installed * React build generated * Files uploaded * Nginx configured * React Router configured (`try_files`) * DNS A record added * SSL installed * HTTPS enabled * Security headers added * Gzip enabled * Browser cache enabled * Logs monitored * Auto SSL renewal working * Nginx starts on boot At this point the React application is running on AWS EC2 behind Nginx with a custom subdomain, HTTPS, basic security hardening, compression, caching, and monitoring support.