Demo Webapp
Architecture & technical notes
A concise, enterprise-style technical overview of the runtime, services, security controls, and operational practices used for this deployment.
System overview
High-level flow
- Browser loads the Next.js web application (pages router).
- UI calls the API gateway under /api.
- The API gateway mounts an Express app for routing and middleware.
- Express routes read/write Postgres via Prisma ORM.
- Uploads are stored either locally (filesystem) or on S3-compatible storage.
Technology stack
Application
- Next.js 12 (React 18) for server-rendered pages and routing.
- Express API mounted via Next API routes for a single deployable service.
- Prisma ORM for schema-driven database access.
Platform services
- PostgreSQL as the primary transactional database.
- Nginx for TLS termination and reverse proxying.
- PM2 + systemd for process supervision.
API design
The API is served under /api and is implemented as an Express application mounted by Next.js at src/pages/api/index.js.
Public endpoints
- Listings: sales, rentals, commercial, sold prices.
- Directory: agent listing and agent profile.
- Lead capture: valuation requests and newsletter subscriptions.
Authenticated endpoints
- Agents: create/update inventory and manage images.
- Users: save/unsave listings, view account context.
- Stats: dashboard metrics and chart-ready aggregates.
Data model
Core entities are normalized for reporting and governance: users, agents, listings, images, saved items, and lead capture records.
Key entities
Entity
Purpose
Agent
Inventory ownership, profile, and publishing identity.
User
Personal account with saved listings.
SalesListing / RentalListing / CommercialListing
Transactional inventory with images and descriptive metadata.
SoldPrice
Market price reference records for search and analysis.
ValuationRequest
Lead intake for valuation workflows with a status field.
NewsletterSubscriber
Opt-in capture with uniqueness constraints.
File storage
Local storage mode
Configurable via STORAGE_PROVIDER=local and LOCAL_STORAGE_ROOT.
- Uploads are written under /uploads/….
- Deletions remove filesystem assets when running in local mode.
S3-compatible storage mode
When STORAGE_PROVIDER=s3, uploads use an S3 client with environment configured credentials.
- Compatible with AWS S3 or S3-compatible endpoints.
- Keys are namespaced and stored in the database alongside listings.
Security controls
Authentication
- JWT-based sessions with server verification on protected endpoints.
- Passwords stored hashed using bcrypt.
- Separate agent vs personal user identities.
Hardening
- Security headers via Helmet middleware.
- CORS middleware configured for API access patterns.
- Schema validation (Zod) for core write operations.
Production hardening (recommended)
- Rate limiting and bot mitigation for public endpoints.
- Audit logging for privileged actions (create/update/delete).
- Structured secrets management and rotation policies.
Operations
Process supervision
- PM2 manages the application process with autorestart.
- systemd service manages PM2 lifecycle for server boot resilience.
Reverse proxy & TLS
- Nginx terminates TLS and proxies requests to the app.
- Static uploads can be served efficiently from the filesystem.
Backups
Postgres backups are scheduled on the host via a systemd timer as documented in the deployment notes.
Quality & roadmap
Current posture
- Functional workflows active: listings, accounts, uploads, and lead capture.
- Schema-driven persistence with relational integrity.
- Operational deployment practices documented and repeatable.
Next steps
- Observability: structured logs + metrics + alerting.
- Test automation and CI for regressions.
- Security hardening items based on stakeholder requirements.