Overview
Mango Capital is a trading and funding platform built at Dubtel. It was a team project. My part covered two areas: owning the delivery pipeline, and building features across the API, the funding portal, and the frontend.
Owning CI/CD
I set up and maintained the GitLab CI pipelines that build Docker images and deploy them to QA and production. Getting them reliable meant working through the failures that only show up on real servers:
- Disk and tmpfs. Deploys failed on full disks and stale tmpfs state. The pipeline now prunes Docker resources before building, cleans up containers and frees ports before starting, and prints diagnostics when something goes wrong.
- Migrations.
flask db upgraderuns on every deploy. It kept hanging because live containers (the API and a Swagger UI) still held database connections. Stopping one service wasn't enough; the reliable fix wasdocker compose downon the whole stack before migrating. - Config. Production configuration is injected from a GitLab file variable at deploy time.
- Provenance. A
/healthendpoint returns the build SHA and timestamp, so anyone can check what's deployed.
Fixing production
- Connection exhaustion. Each gunicorn worker opens its own SQLAlchemy pool. Four workers with default pools, plus other containers, exceeded the managed Postgres limit. I cut the workers to two, capped each pool at 3 connections plus 2 overflow (10 total), and wrote that arithmetic into the config. The managed database sits behind PgBouncer, which also needed
sslmode=requireon every connection URL. - Surprise JOINs. A relationship declared
lazy="joined"added a JOIN to every user lookup. Switching it toselectmade the hot path cheaper. - CORS with credentials. Browsers reject a wildcard origin on credentialed requests. The API now reflects the request's
Originfor allowed origins. I briefly replaced Flask-CORS with a hand-written handler, then went back to Flask-CORS once it was configured correctly, because less custom code is better. - Logging that crashed logins. A failure writing a log row to the database turned logins into 500s. Logging failures are now caught and never fail the request.
Features
- Trading: trades and profitability report pages with pagination, and the buy-model screens.
- Funding: a listing of all submitted funding requests for admins, admin notes, and email notifications to funders, requesters, and the company.
- Billing: billing models and endpoints with Swagger docs, and server-side PDF invoices with WeasyPrint. WeasyPrint's limited flexbox support needed a table-based layout.
- White-label support: tenant logo upload to object storage, used in the login response and on PDF invoices.
