CASE STUDY

Siklo

Software project lifecycle tracker

Siklo, Filipino for “cycle”, is an internal system for a software team. It follows every project from the first plan through approval, development, launch and maintenance until it is shut down, and it keeps tracking after launch: hosting costs, renewals, maintenance and client payments. I designed and built all of it on my own, from the database schema and API to the interface and tests.

Role
Solo developer, design to testing
Type
Personal project
Status
Live demo
The Siklo dashboard

35

API modules

49

Database tables

197

Documented routes

49

Test files

01.The problem

A software team's work doesn't end at launch. Each system still needs hosting, renewals, fixes and maintenance, and the client still owes payments. When that lives in chat threads, spreadsheets and memory, it's hard to see which projects are at risk, what each one really costs, or who hasn't paid.

Siklo keeps the whole life of a project in one place. Every stage change is checked and recorded, tickets and milestones show real progress, and after launch the same project carries its costs, billing, maintenance and incidents until it is shut down and archived.

It's deliberately a record-keeping tool for one organization. Payments are recorded, not processed, and it issues no official receipts and computes no VAT.

02.What it does

Lifecycle and pipeline

Projects move through eight stages on a drag-and-drop pipeline. Each move checks its own requirements, such as a proposal, a signed approval, a UAT sign-off or a logged production deployment, and records who moved it and why.

Phases

Phase 1 is the initial build and drives the project's stage. A later phase, like a v2, runs its own pipeline card while the project stays Live, so hosting and billing carry on.

Tickets and progress

Features, bugs, tasks, change requests and support tickets on a kanban with rank ordering and live updates. Milestones show progress from estimate points and flag work that is at risk or overdue.

Time, comments and approvals

Programmers log time per ticket against the estimate. Comments support @mentions, attachments and internal notes, and approvals keep the signed document behind each decision.

Costs and renewals

Expenses by category, with recurring templates for hosting, domains and licenses. Renewals send reminders 30, 7 and 1 day ahead, and every project shows its running cost.

Billing and payments

A daily job generates service billing records 15 days before they are due. Contract downpayments, milestones and final payments share one table, and payments can be partial but are never edited, only voided with a reason.

Deployments and maintenance

A deployment log per environment, maintenance schedules and records, and incidents that link to the tickets that fixed them.

Chat, portal and reports

A chat channel per project plus DMs over Socket.IO. Clients get a separate portal with their progress, tickets and billing. A dashboard and reports share one set of formulas and export to CSV and PDF.

03.Inside the app

The Siklo pipeline board with projects grouped by stage
The pipeline. Dragging a card runs the same checked stage change as the Move stage button.
The Siklo projects list with stage, progress and contract columns
Every project with its stage, progress, risk and contract amount, as a list or cards.
A Siklo project page with its lifecycle track and ticket kanban
A project's lifecycle track and its ticket kanban, with per-project ticket codes.

04.The lifecycle

Every project follows the same stages. Each forward move has its own requirement, some moves can go back with a note, and only an Admin can approve, shut down, archive or cancel.

STAGES

  1. Planning
  2. Approval
  3. Development
  4. Testing/UAT
  5. Deployment
  6. Live
  7. Maintenance
  8. Shutdown
  9. Archived

BEFORE LAUNCH

Approval needs a signed document. Live needs a logged production deployment.

Moving to Deployment warns about open urgent bugs, and a project can be cancelled with a reason before it goes live.

AFTER LAUNCH

Maintenance needs an active service plan. Archiving needs a finished shutdown checklist.

Archiving warns about any unpaid balance, and an archived project can never be reopened.

Every move is checked, recorded and on the project's timeline.

Admin, Project Manager, Finance, Programmer and Client each map to permission codes enforced by the API

05.Engineering decisions

Every stage change is guarded

Each move has a rule for who may make it and what it needs, kept in one table of cases that both the API and the tests read. A project on hold can't move until it is released, and a backward move needs a note.

Money never reaches programmers

Cost, contract amount, payments and profit are removed by the API, not just hidden in the UI. A contract test reads every route a programmer can call and fails if any money field comes back.

No access means 404, not 403

A user who isn't on a project can't tell it exists. Project isolation is checked on every project route by a contract test, and clients only ever see the simplified statuses and their own records.

Archived is permanent

There is no reopen. Every write on an archived project answers 409 PROJECT_ARCHIVED, chat history included, so the archive stays a reliable record of what happened.

Money in centavos, payments never edited

All amounts are PHP stored as bigint centavos. Overpayment is refused, a mistake is voided with a reason instead of edited, and an invariant check proves billing and payments reconcile after every scenario.

Private files by default

Attachments are authenticated Cloudinary assets behind one storage service. A download is a short-lived signed link, issued only after the same permission check as the record it belongs to.

06.Testing

Access and money rules have to hold on every route, including ones added later. Alongside its feature tests, the API's Vitest and Supertest suite has contract tests that check those rules across the whole API.

  • ▸Tests run in-process against a real PostgreSQL database and a real Redis, with nothing in the data path mocked.
  • ▸Contract tests fail the suite on a route with no permission check, a write with no audit row, a cache with no invalidator, money a programmer could read, or internal data in the client portal.
  • ▸Every route must have a row in the API docs with the right access code, and a route coverage guard fails the suite if any route has no passing test.
  • ▸A full day runs through the API from start to finish, and a concurrency suite fires conflicting writes at once to prove tickets, billing and payments stay correct.
  • ▸A load check builds a database with 200 projects, 100,000 tickets and 500,000 messages and times every list, board, report and the dashboard against its budget.

07.Tech stack

  • TypeScript
  • Express 5
  • React 19 (Vite)
  • TanStack Router, Query & Table
  • Base UI
  • Tailwind CSS
  • dnd-kit
  • PostgreSQL
  • Drizzle ORM
  • Redis
  • Socket.IO
  • Cloudinary
  • Resend
  • Zod
  • Recharts
  • Vitest
  • Docker
  • Sentry

The interface has its own “Mission Control” theme, a blueprint-paper light mode and a control-room dark mode, with every text pair checked for WCAG AA contrast in both. Heavy libraries like dnd-kit and the charts load only on the pages that use them.

Losing track of your projects after launch?

I build business systems end to end: the records, the checks and the tests that keep them correct. Let's talk about yours.