841 lines
28 KiB
Markdown
841 lines
28 KiB
Markdown
# Headroom - Complete Decision Log & Conversation Archive
|
||
|
||
**Version:** 1.0
|
||
**Date:** February 17, 2026
|
||
**Participants:** Santhosh J (Project Owner), AI Assistant (Design Partner)
|
||
**Purpose:** Comprehensive record of all discussions, decisions, considerations, and deferrals
|
||
|
||
---
|
||
|
||
## Table of Contents
|
||
|
||
1. [Project Genesis](#project-genesis)
|
||
2. [Requirements Discovery](#requirements-discovery)
|
||
3. [Technical Stack Decisions](#technical-stack-decisions)
|
||
4. [Architecture Decisions](#architecture-decisions)
|
||
5. [Quality & Testing Decisions](#quality--testing-decisions)
|
||
6. [Deferred Features](#deferred-features)
|
||
7. [Rejected Options](#rejected-options)
|
||
8. [Open Questions](#open-questions)
|
||
9. [Timeline](#timeline)
|
||
|
||
---
|
||
|
||
## Project Genesis
|
||
|
||
### The Problem
|
||
|
||
**Context:**
|
||
- Managing team of 10-15 developers
|
||
- Handling 10-12 concurrent projects in various phases
|
||
- Currently using spreadsheets → "a nightmare"
|
||
|
||
**Pain Points Identified:**
|
||
1. **Capacity calculation chaos**: Manual calculations across holidays, PTO, weekends
|
||
2. **No validation**: Easy to over-allocate people or projects
|
||
3. **Visibility gap**: Hard to answer "Who has headroom for new work?"
|
||
4. **Billing errors**:
|
||
- Over-allocation → Overcharge clients → Escalations
|
||
- Under-allocation → Undercharge → Revenue loss
|
||
5. **No audit trail**: Changes are invisible
|
||
6. **Actual vs Planned tracking**: Difficult to compare what was planned vs what actually happened
|
||
|
||
### The Vision
|
||
|
||
**Product Name:** Headroom
|
||
- **Why this name?** It's the word managers actually say ("do we have headroom for this?"), immediately signals capacity planning, and captures the over/under allocation anxiety central to the tool.
|
||
- **Close runner-up:** Margin (protecting margin through accurate forecasting)
|
||
|
||
**Core Value:**
|
||
> Know exactly who has headroom for new work, prevent billing errors, forecast revenue, track planned vs actual hours.
|
||
|
||
### Personas
|
||
|
||
Four distinct user types identified:
|
||
|
||
| Persona | Primary Need |
|
||
|---------|--------------|
|
||
| **Superuser** | System setup, configuration, admin controls |
|
||
| **Managers** | Resource planning, allocation, team oversight |
|
||
| **Developers** | View allocations, log hours, understand workload |
|
||
| **Top Brass** | Executive reports, forecasts, budget visibility |
|
||
|
||
---
|
||
|
||
## Requirements Discovery
|
||
|
||
### The Monthly Cycle
|
||
|
||
**Key Insight:** The workflow is organized around monthly capacity planning cycles, not continuous allocation.
|
||
|
||
```
|
||
Monthly Cycle:
|
||
1. Capacity Planning → Who's available, how much?
|
||
2. Project Setup → What work needs to be done?
|
||
3. Resource Allocation → Who does what?
|
||
4. Actuals Tracking → What actually happened?
|
||
```
|
||
|
||
### Capacity Planning Requirements
|
||
|
||
**Inputs:**
|
||
- Team member list (name, role, hourly rate)
|
||
- Calendar data (holidays, weekends)
|
||
- Individual PTO requests
|
||
- Daily availability: **0** (unavailable), **0.5** (half day), **1.0** (full day)
|
||
|
||
**Critical Clarification:**
|
||
- Initial assumption: "10 hrs for Dev" meant role-based allocation
|
||
- **Actual requirement:** Person-specific allocation ("10 hrs for Santhosh")
|
||
- Availability is per-person, per-day, not role-based
|
||
|
||
**Outputs Needed:**
|
||
1. Individual capacity (person-days per month)
|
||
2. Team capacity summary (total available person-days)
|
||
3. Possible revenue (if fully utilized)
|
||
|
||
### Project Management Requirements
|
||
|
||
**Project Lifecycle:**
|
||
|
||
```
|
||
NA/Support → Initial → Gathering Estimates → Estimate Pending Approval
|
||
↓
|
||
Estimate Rework ←───────┘
|
||
↓
|
||
Estimate Approved → Funded → Scheduled → In-Progress
|
||
↓
|
||
Ready for Prod → Done
|
||
↓
|
||
[Optional: On-Hold, Cancelled]
|
||
```
|
||
|
||
**Key Attributes:**
|
||
- **Approved Estimate**: Total billable hours approved by client
|
||
- **Forecasted Effort**: How those hours split across months
|
||
- **Project Type**: Project (billable) vs Support (ongoing ops)
|
||
|
||
**Validation Requirement:**
|
||
- **Over-forecast**: Allocated hours > Approved estimate → RED FLAG (will overcharge)
|
||
- **Under-forecast**: Allocated hours < Approved estimate → YELLOW FLAG (will undercharge)
|
||
- **Clarification:** "Under-forecast is NOT OK. This money is my salary! Always try to be 100%."
|
||
|
||
### Resource Allocation Requirements
|
||
|
||
**The "Matrix" Concept:**
|
||
|
||
```
|
||
For month M:
|
||
┌────────────────────────────────────────┐
|
||
│ Project │ Dev A │ Dev B │ Dev C │ Ext │
|
||
├──────────┼───────┼───────┼───────┼─────┤
|
||
│ Proj X │ 40h │ 20h │ 0 │ 10h │
|
||
│ Proj Y │ 20h │ 40h │ 30h │ 0 │
|
||
└────────────────────────────────────────┘
|
||
```
|
||
|
||
**"Untracked Resource" Requirement:**
|
||
- Purpose: Accommodate hours for external team members (e.g., DevOps from another team)
|
||
- Billing: NOT tracked for revenue (like a joker in a deck of cards)
|
||
- Use case: "We might bill another team, but not track their specific person"
|
||
|
||
**Validation Rules:**
|
||
- Sum of project allocations should equal approved estimate (tolerance: ±5%)
|
||
- Cannot allocate more than person's monthly capacity (warning, not hard block)
|
||
- Visual indicators: GREEN (100%), YELLOW (<100%), RED (>100%)
|
||
|
||
### Actuals Tracking Requirements
|
||
|
||
**Data Entry:**
|
||
- **Frequency**: Monthly aggregate, but can be updated incrementally (weekly)
|
||
- **Method**: Manual entry (no time-tracking tool integration for MVP)
|
||
|
||
**Calculations:**
|
||
- **Running utilization**: (Allocated hours YTD) / (Capacity YTD) × 100%
|
||
- **Overall utilization**: (Allocated hours this month) / (Capacity this month) × 100%
|
||
|
||
**Display Requirement:**
|
||
- Show utilization % alongside capacity view
|
||
|
||
### Reporting Requirements
|
||
|
||
**Core Reports:**
|
||
1. **Forecast Summary** (multi-period)
|
||
2. **Utilization Summary**
|
||
3. **Cost Summary**
|
||
|
||
**Critical Requirement:**
|
||
> All reports must be highly customizable with filters (team, person, project, status, date range, type)
|
||
|
||
**Additional Requirements:**
|
||
- Master data / taxonomy for configurable items (roles, statuses, types)
|
||
- Support for multi-tenancy (deferred to post-MVP)
|
||
|
||
---
|
||
|
||
## Technical Stack Decisions
|
||
|
||
### Backend: Why Laravel?
|
||
|
||
**Question Raised:** "I chose Laravel because of my PHP background. Debate me if that is not a good choice."
|
||
|
||
**Consideration:**
|
||
- Alternative: SvelteKit full-stack (single framework)
|
||
- Alternative: Next.js + Node.js
|
||
|
||
**Decision:** Laravel
|
||
- **Rationale**:
|
||
- You have PHP background (lower learning curve)
|
||
- Laravel is mature, robust for API development
|
||
- Rich ecosystem (Scribe for API docs, Pest for testing, Pint for linting)
|
||
- PostgreSQL support is excellent
|
||
- Redis integration is first-class
|
||
|
||
**No pushback from AI:** Laravel is a solid choice for this use case.
|
||
|
||
### Frontend: The Great Debate
|
||
|
||
**Initial Question:** "May be Laravel + Svelte? Or Sveltekit itself?"
|
||
|
||
**Options Presented:**
|
||
1. Laravel + Blade Templates (rejected: less interactive)
|
||
2. Laravel + Vue.js (recommended by AI: stay in Laravel ecosystem)
|
||
3. **Laravel API + SvelteKit (separate)** ← CHOSEN
|
||
4. Laravel API + React (rejected: more learning curve)
|
||
|
||
**Decision:** Laravel API + SvelteKit (separate projects)
|
||
- **Your choice:** "Sveltekit it is!"
|
||
- **AI concern:** "Adds deployment complexity for MVP"
|
||
- **Your response:** "I will choose this."
|
||
- **Outcome:** Two separate containers, clean separation
|
||
|
||
**Why SvelteKit?**
|
||
- Modern, reactive
|
||
- Great for data-heavy dashboards
|
||
- Smaller bundle sizes than React/Vue
|
||
- You're willing to learn it
|
||
|
||
### Database: PostgreSQL from Day 1
|
||
|
||
**Question:** "SQLite for local, PostgreSQL for production?"
|
||
|
||
**Decision:** PostgreSQL from the start
|
||
- **Rationale**:
|
||
- Avoid migration pain later
|
||
- Production-grade features (JSON operators, full-text search)
|
||
- Better for reporting queries
|
||
- Volume-mounted in Docker (portability maintained)
|
||
|
||
### Caching: Redis from Day 1
|
||
|
||
**Initial Recommendation:** "Start without caching, add in Phase 2 if slow"
|
||
|
||
**Your Response:** "Query caching and Response caching on Redis from Day 1. No need to sweat on refactoring it everywhere."
|
||
|
||
**Decision:** Redis caching from day 1
|
||
- **Rationale**: Prevents technical debt
|
||
- **Scope**: Query caching + Response caching
|
||
- **Implementation**: Laravel cache facade, automatic invalidation
|
||
|
||
### Authentication: JWT
|
||
|
||
**Question:** "Session-based or Token-based (JWT)?"
|
||
|
||
**AI Recommendation:** "Session-based is easier for same-origin setup"
|
||
|
||
**Your Choice:** "I will go with JWT."
|
||
|
||
**Rationale:**
|
||
- Token-based authentication
|
||
- Suitable for SPA frontend
|
||
- Easier to add mobile app later (if needed)
|
||
|
||
### UI Component Library
|
||
|
||
**Options Presented:**
|
||
- Shadcn/ui (headless, customizable)
|
||
- **DaisyUI** (Tailwind-based, fast) ← CHOSEN
|
||
- Svelte Material UI (full-featured)
|
||
- Build custom with Tailwind
|
||
|
||
**Decision:** DaisyUI
|
||
- **Rationale**: Faster to build dashboards, opinionated but fast
|
||
- **Your response:** "Daisy it is."
|
||
|
||
### Charts & Visualization
|
||
|
||
**Options Presented:**
|
||
- **Recharts** ← CHOSEN (AI recommendation)
|
||
- Chart.js
|
||
- Plotly
|
||
- Apache ECharts
|
||
|
||
**Decision:** Recharts
|
||
- **Rationale**: Good balance of power and simplicity
|
||
- **Your response:** "Agreed"
|
||
|
||
### Tables & Data Grid
|
||
|
||
**Options Presented:**
|
||
- **TanStack Table (React Table)** ← CHOSEN
|
||
- Svelte DataTable
|
||
- Build custom
|
||
|
||
**Decision:** TanStack Table
|
||
- **AI note:** "I am not familiar with this, but I will go with your recommendation."
|
||
- **Rationale**: Industry standard, powerful filtering/sorting, works with Svelte
|
||
|
||
### Forms & Validation
|
||
|
||
**Options Presented:**
|
||
- SvelteKit Form Actions + Superforms
|
||
- Direct API calls
|
||
|
||
**Additional Question:** "How about something like Superform or Zod?"
|
||
|
||
**Decision:** Superforms + Zod + SvelteKit Form Actions
|
||
- **Rationale**:
|
||
- Type-safe validation (Zod)
|
||
- Form state management (Superforms)
|
||
- Server-side handling (SvelteKit native)
|
||
- Single source of truth for validation
|
||
|
||
### API Documentation
|
||
|
||
**Question Raised:** "How about SwaggerUI documentation for APIs?"
|
||
|
||
**Decision:** Laravel Scribe (auto-generates SwaggerUI)
|
||
- **Implementation**: `composer require knuckleswtf/scribe`
|
||
- **Output**: `/api/documentation` endpoint with OpenAPI spec
|
||
- **Lift**: ~1 hour setup
|
||
- **Inclusion**: From day 1
|
||
|
||
### Testing Stack
|
||
|
||
**Backend:**
|
||
- PHPUnit (unit tests)
|
||
- Pest (feature tests)
|
||
|
||
**Frontend:**
|
||
- Vitest (unit tests)
|
||
- Playwright (E2E tests)
|
||
|
||
**Decision:** Include all from day 1
|
||
|
||
### Version Strategy
|
||
|
||
**Question:** Which versions to use?
|
||
|
||
**Decision:** Use latest versions across the stack
|
||
- **Laravel 12** (latest major version)
|
||
- **PHP 8.4** (compatible with Laravel 12)
|
||
- **All other dependencies:** Use `:latest` tags (PostgreSQL, Redis, Node, npm packages)
|
||
|
||
**Rationale:**
|
||
- Stay current with latest features and security patches
|
||
- Avoid version lock-in from the start
|
||
- Docker `:latest` tags ensure fresh installs get newest versions
|
||
|
||
---
|
||
|
||
## Architecture Decisions
|
||
|
||
### Containerization
|
||
|
||
**Requirement:** "From get go, everything must be containerised."
|
||
|
||
**Additional Constraint:** "Do not add any proxy manager (NPM, Caddy, or Traefik). My environment already runs an NPM."
|
||
|
||
**Decision:** Docker Compose with 4 containers
|
||
1. **Frontend**: SvelteKit (port 5173)
|
||
2. **Backend**: Laravel (port 3000)
|
||
3. **Database**: PostgreSQL (port 5432)
|
||
4. **Cache**: Redis (port 6379)
|
||
|
||
**Reverse Proxy:**
|
||
- Use existing Nginx Proxy Manager
|
||
- NPM routes `/api/*` → Laravel
|
||
- NPM routes `/*` → SvelteKit
|
||
|
||
### Multi-Tenancy
|
||
|
||
**Question:** "Should we build multi-tenant from day 1?"
|
||
|
||
**AI Recommendation:** "Start single-tenant. Add tenant_id column when needed."
|
||
|
||
**Your Response:** "AGREED"
|
||
|
||
**Rationale:** Reduces complexity, easy to add later
|
||
|
||
### Environment Configuration
|
||
|
||
**Question:** ".env files or Docker secrets?"
|
||
|
||
**AI Recommendation:** ".env files for local, Docker secrets in prod"
|
||
|
||
**Your Response:** ".env everywhere"
|
||
|
||
**Decision:** .env files in all environments
|
||
- Simpler configuration management
|
||
- Consistent across local/prod
|
||
|
||
### Development Environment
|
||
|
||
**Question:** "Docker Compose for local dev, or native setup?"
|
||
|
||
**AI Recommendation:** "Docker Compose from the start. Ensures prod parity."
|
||
|
||
**Your Response:** "100% agree. If possible, we should have at least the local dev avoid building after every change (may be code mounted)"
|
||
|
||
**Decision:** Docker Compose with code-mounted volumes
|
||
- Hot reload for both frontend and backend
|
||
- Avoid rebuilding containers on every change
|
||
- Volume mounts: `./frontend:/app`, `./backend:/var/www`
|
||
|
||
### Real-Time Updates
|
||
|
||
**Question:** "Do you need live updates (WebSockets), or is polling OK?"
|
||
|
||
**AI Recommendation:** "Start with polling. Add WebSockets if needed."
|
||
|
||
**Your Response:** "I dont think we need to sweat on it. Go with a basic implementation. Polling is good enough."
|
||
|
||
**Decision:** Polling (defer WebSockets to Phase 2)
|
||
|
||
### State Management (Frontend)
|
||
|
||
**Question:** "Svelte stores for UI state, or always fetch from API?"
|
||
|
||
**AI Recommendation:** "Use Svelte stores for UI state (filters, modals), API queries for data."
|
||
|
||
**Your Response:** "Agreed."
|
||
|
||
**Decision:** Minimal Svelte stores (UI state only)
|
||
|
||
### Report Exports
|
||
|
||
**Question:** "Will users need PDF/CSV exports?"
|
||
|
||
**AI Recommendation:** "Start with on-screen reports, add exports in phase 2."
|
||
|
||
**Your Initial Response:** "Good to have at this time."
|
||
|
||
**AI Clarification:** "Should exports be in MVP scope, or phase 2?"
|
||
|
||
**Final Decision:** Phase 2
|
||
- **Rationale**: Keeps MVP scope tight, adds 4 hours of work
|
||
- Interactive dashboard is primary value
|
||
|
||
### Caching Strategy
|
||
|
||
**Question Raised by You:** "Should we talk about a caching layer?"
|
||
|
||
**Options Discussed:**
|
||
1. Database Query Caching
|
||
2. API Response Caching
|
||
3. Full-page caching
|
||
|
||
**AI Recommendation:** "Start without caching, add Redis in Phase 2 if slow"
|
||
|
||
**Your Response:** "Query caching and Response caching on Redis from Day 1. No need to sweat on refactoring it everywhere."
|
||
|
||
**Decision:** Redis caching from day 1
|
||
- Query caching (expensive calculations)
|
||
- Response caching (GET endpoints)
|
||
- Automatic cache invalidation on mutations
|
||
- TTL: 1 hour (allocations), 15 min (reports), 24 hours (master data)
|
||
|
||
---
|
||
|
||
## Quality & Testing Decisions
|
||
|
||
### Project-Level Standing Instructions
|
||
|
||
**Your 5 Points (to be encoded in OpenSpec config.yml):**
|
||
|
||
1. **Every change must have unit tests, E2E test, regression tests** (whether prompted or not)
|
||
2. **Changes must end with code review** for style, standard, security
|
||
3. **Verification (`/opsx-verify`) must trigger checking of uncovered code** (code not tested)
|
||
4. **Commits must be granular** (one fix = one commit)
|
||
5. **Tests run in a progressive loop**:
|
||
- Test → Create issue in repo → Fix → Retest + Regression test
|
||
- Loop until all issues fixed
|
||
|
||
**AI Question:** "Is this for ALL tests, or specifically for E2E/integration tests?"
|
||
|
||
**Your Clarification:** "I agree. Let us go for a kill only in E2E and Integration."
|
||
|
||
**AI Concern:** "This workflow can slow velocity. For MVP, start with 'every test must pass before merge' and defer granular issue-loop to phase 2?"
|
||
|
||
**Your Response:** "Agreed"
|
||
|
||
**Final Decision:**
|
||
- **MVP**: All tests must pass, granular commits, code review
|
||
- **Phase 2**: Issue-driven test loop for E2E/integration failures
|
||
|
||
### Code Coverage Threshold
|
||
|
||
**AI Question:** "What code coverage % for /opsx-verify?"
|
||
|
||
**Your Response:** "Let us call it >70%"
|
||
|
||
**Decision:** >70% code coverage required
|
||
- Checked in `/opsx-verify`
|
||
- Blocks merge if below threshold
|
||
|
||
### Data Validation Rules
|
||
|
||
**AI Question:** "Should we document validation rules in OpenSpec?"
|
||
|
||
**Your Response:** "OpenSpec document must have all required data. I believe we need it there for verification and regression tests. Thoughts?"
|
||
|
||
**AI Agreement:** "Absolutely. Rules inform API implementation, test cases, and verification."
|
||
|
||
**Decision:** Create `validation-rules.md` in OpenSpec changes
|
||
- These rules drive Laravel validation
|
||
- Inform test case generation
|
||
- Used in `/opsx-verify`
|
||
|
||
### RBAC (Role-Based Access Control)
|
||
|
||
**AI Question:** "Can a Manager see only their projects, or all projects?"
|
||
|
||
**Your Clarification:** "Can see all projects. But not allocate to other team's members."
|
||
|
||
**Decision:** RBAC Matrix defined
|
||
|
||
| Persona | Can See | Can Modify |
|
||
|---------|---------|------------|
|
||
| Superuser | All | All |
|
||
| Manager | All projects (read-only for others') | Own projects, own team allocations |
|
||
| Developer | Own allocations, assigned projects | Own actuals only |
|
||
| Top Brass | All reports | Nothing (read-only) |
|
||
|
||
---
|
||
|
||
## Deferred Features
|
||
|
||
### Phase 2 Deferrals
|
||
|
||
| Feature | Reason for Deferral | Estimated Lift |
|
||
|---------|---------------------|----------------|
|
||
| **Notifications (WebSocket)** | Allocations are monthly, not time-critical | ~6 hours |
|
||
| **PDF/CSV Exports** | On-screen reports sufficient for MVP | ~4 hours |
|
||
| **Background Jobs** | No heavy processing in MVP, Laravel Queue ready | ~2 hours |
|
||
| **Audit Logging** | No compliance requirement for MVP | ~3 hours |
|
||
| **Advanced Caching (pre-calculated reports)** | Start with on-demand queries | ~4 hours |
|
||
| **API Versioning (`/api/v1/`)** | Not needed until breaking changes | ~2 hours |
|
||
| **Issue-driven test loop** | Slower velocity for MVP | ~8 hours |
|
||
|
||
### Notifications Deep-Dive
|
||
|
||
**AI Presented 3 Options:**
|
||
|
||
**Option A:** Include WebSocket + 1 notification PoC (~6 hours)
|
||
- Pros: Real-time updates, framework ready
|
||
- Cons: Adds complexity, delays other features by ~1 day
|
||
|
||
**Option B:** Skip notifications entirely for MVP
|
||
- Pros: Keeps scope tight, faster MVP
|
||
- Cons: Users must refresh to see changes
|
||
- **Debt accrual:** Low (easy to add later)
|
||
|
||
**Option C:** Polling-based notifications (~2 hours)
|
||
- SvelteKit polls every 30s
|
||
- Pros: Simple, users see changes quickly
|
||
- Cons: Not true real-time, more server load
|
||
|
||
**AI Recommendation:** Option B (skip for MVP)
|
||
|
||
**Your Question:** "Wont it become a technical debt? How big the lift will be to at least set up the wiring for notifications (websocket setup and one notification implemented as a proof of concept?)"
|
||
|
||
**AI Response:** "6 hours total lift. Not worth it for MVP - allocations are monthly, not time-critical."
|
||
|
||
**Your Decision:** "Ok. Option B."
|
||
|
||
---
|
||
|
||
## Rejected Options
|
||
|
||
### Options Considered but Not Chosen
|
||
|
||
| Option | Why Rejected |
|
||
|--------|--------------|
|
||
| **Laravel + Blade Templates** | Less interactive UI, harder to build dashboards |
|
||
| **Laravel + Vue.js** | You preferred learning Svelte over Vue |
|
||
| **Next.js + Node.js** | You have PHP background, prefer Laravel |
|
||
| **SQLite for local dev** | Avoid migration pain, PostgreSQL from start |
|
||
| **Session-based auth** | JWT chosen for future mobile support |
|
||
| **Multi-tenancy from day 1** | Adds complexity, defer to post-MVP |
|
||
| **WebSocket notifications in MVP** | Not time-critical, 6 hours of work |
|
||
| **PDF/CSV exports in MVP** | On-screen reports sufficient initially |
|
||
| **GraphQL** | REST is simpler for MVP |
|
||
| **Chart.js / Plotly / ECharts** | Recharts chosen (good balance) |
|
||
| **Shadcn/ui / Svelte Material UI** | DaisyUI chosen (faster development) |
|
||
| **Custom-built table component** | TanStack Table chosen (industry standard) |
|
||
|
||
---
|
||
|
||
## Open Questions (Resolved)
|
||
|
||
### 1. Over/Under Forecast Context
|
||
|
||
**Initial Confusion:** "Is over/under forecast about allocation vs approved estimate, or allocation vs capacity?"
|
||
|
||
**Your Clarification:** "In the project's context, yes. it is allocation vs approved. (For the future phases, there will be over/under forecast for resources - that will be based on individual's allocation vs their capacity. May be we can keep that aside for now.)"
|
||
|
||
**Example Correction:**
|
||
- **AI Example:** "Month 1 allocation: 80hrs → Under-forecast (OK)"
|
||
- **Your Correction:** "Not OK. Because this money is my salary! We always try to be on par - 100%. If it is under-forecast, call that out."
|
||
|
||
**Resolution:** Both over and under-forecast are flagged. Under is YELLOW, Over is RED.
|
||
|
||
### 2. Availability Model
|
||
|
||
**Initial Confusion:** "Is availability 1.0 = 8 hours/day, or is it a percentage?"
|
||
|
||
**Your Clarification:** "Hours per day must be configurable per project. 1 means, 100% of a productive day. .5 means half of that and so on. I dont want to make it too granular thats why I had stops on 1, .5 and 0. Then there are H - holidays and O- weekend offs."
|
||
|
||
**Resolution:** Availability is 0, 0.5, or 1.0 (not percentage). 0 = unavailable or PTO.
|
||
|
||
### 3. Untracked Resource Purpose
|
||
|
||
**Initial Confusion:** "Is this for contractors, or overhead?"
|
||
|
||
**Your Clarification:** "We might have some time allocated for DevOps team which is not part of my team but might out bill to another team. For that purpose."
|
||
|
||
**Resolution:** Untracked resource is for external team time (not billed in this system).
|
||
|
||
### 4. Team Structure
|
||
|
||
**Initial Confusion:** "Does 'Team' mean sub-teams?"
|
||
|
||
**Your Clarification:** "Yes. Read that as 'Role'."
|
||
|
||
**Resolution:** Team = Role (e.g., Frontend, Backend, QA, PM, Architect).
|
||
|
||
### 5. Manager Permissions
|
||
|
||
**Initial Confusion:** "Can a Manager allocate to projects outside their team?"
|
||
|
||
**Your Clarification:** "Can see. But not allocate to other team's members."
|
||
|
||
**Resolution:** Managers see all projects (read-only for others'), but can only allocate their own team members.
|
||
|
||
---
|
||
|
||
## Timeline
|
||
|
||
### Conversation Flow
|
||
|
||
**February 17, 2026:**
|
||
|
||
1. **Initial Problem Statement** (09:00-09:30)
|
||
- You described the spreadsheet nightmare
|
||
- Identified 4 personas
|
||
- Outlined capacity planning → allocation → actuals flow
|
||
|
||
2. **Requirements Deep-Dive** (09:30-11:00)
|
||
- Clarified capacity planning details (availability model)
|
||
- Defined project lifecycle states
|
||
- Detailed allocation matrix requirements
|
||
- Discussed reporting needs
|
||
|
||
3. **Technical Stack Discussion** (11:00-12:00)
|
||
- Debated Laravel vs alternatives → Laravel chosen
|
||
- Frontend: Vue vs Svelte → SvelteKit chosen
|
||
- Database: SQLite vs PostgreSQL → PostgreSQL chosen
|
||
- Authentication: Session vs JWT → JWT chosen
|
||
|
||
4. **Architecture Decisions** (12:00-13:00)
|
||
- Containerization approach (Docker Compose)
|
||
- Multi-tenancy deferral
|
||
- Caching strategy (Redis from day 1)
|
||
- Real-time updates (polling, defer WebSockets)
|
||
|
||
5. **Quality Standards** (13:00-13:30)
|
||
- Testing requirements (>70% coverage)
|
||
- Code review process
|
||
- Commit standards (granular)
|
||
- Issue-driven test loop (defer to Phase 2)
|
||
|
||
6. **Frontend Libraries** (13:30-14:00)
|
||
- UI components: DaisyUI chosen
|
||
- Charts: Recharts chosen
|
||
- Tables: TanStack Table chosen
|
||
- Forms: Superforms + Zod chosen
|
||
|
||
7. **Final Verification** (14:00-14:30)
|
||
- Reviewed complete architecture
|
||
- Confirmed no missing pieces
|
||
- Decided on API documentation (Scribe)
|
||
- Named the project: **Headroom**
|
||
|
||
8. **Documentation Request** (14:30-15:00)
|
||
- Request for comprehensive documentation
|
||
- Mermaid diagrams
|
||
- Word document for hardcopy
|
||
|
||
### Key Turning Points
|
||
|
||
**Moment 1: Naming the Project**
|
||
- You chose "Headroom" over "Margin"
|
||
- This crystallized the product's identity
|
||
|
||
**Moment 2: SvelteKit Decision**
|
||
- Despite AI recommending Laravel + Vue (easier)
|
||
- You chose SvelteKit (more learning, cleaner separation)
|
||
- This showed willingness to learn for better architecture
|
||
|
||
**Moment 3: Redis from Day 1**
|
||
- AI recommended deferring caching
|
||
- You insisted on Redis from day 1 (avoid refactoring debt)
|
||
- This showed pragmatic technical judgment
|
||
|
||
**Moment 4: "This money is my salary!"**
|
||
- Clarified that under-forecast is NOT acceptable
|
||
- Both over and under-forecast must be flagged
|
||
- This revealed the business criticality of accurate allocation
|
||
|
||
**Moment 5: "One last check before we lock in"**
|
||
- You paused before committing to the stack
|
||
- Requested comprehensive review
|
||
- This showed careful, deliberate decision-making
|
||
|
||
---
|
||
|
||
## Considerations & Trade-offs
|
||
|
||
### Decision Matrix
|
||
|
||
| Decision | Benefit | Cost | Rationale |
|
||
|----------|---------|------|-----------|
|
||
| **SvelteKit (separate)** | Clean separation, modern framework | Deployment complexity, learning curve | Better long-term architecture |
|
||
| **Redis from day 1** | No refactoring debt later | Slightly more upfront setup | Prevents future pain |
|
||
| **JWT over sessions** | Mobile-ready, stateless | More complex than sessions | Future-proofing |
|
||
| **PostgreSQL from day 1** | No migration later | Heavier than SQLite | Production-grade from start |
|
||
| **Defer notifications** | Faster MVP | Users must refresh | Not time-critical for monthly planning |
|
||
| **Defer exports** | Tighter scope | No PDF/CSV initially | On-screen reports are primary value |
|
||
| **TanStack Table** | Powerful, standard | Learning curve (you're unfamiliar) | Industry best practice |
|
||
| **DaisyUI** | Fast development | Opinionated | Speed > customization for MVP |
|
||
|
||
### Risk Assessment
|
||
|
||
**Low Risk:**
|
||
- Laravel choice (you have PHP background)
|
||
- PostgreSQL choice (mature, well-supported)
|
||
- Redis choice (simple, well-integrated with Laravel)
|
||
|
||
**Medium Risk:**
|
||
- SvelteKit choice (learning curve, but modern and well-documented)
|
||
- TanStack Table (unfamiliar to you, but powerful)
|
||
- Two-container deployment (more moving parts, but cleaner)
|
||
|
||
**Mitigated Risks:**
|
||
- **Over-complexity:** Deferred features to Phase 2 (notifications, exports, multi-tenancy)
|
||
- **Performance:** Redis caching from day 1
|
||
- **Testing debt:** >70% coverage enforced from day 1
|
||
|
||
---
|
||
|
||
## Success Metrics (Defined)
|
||
|
||
### MVP Success Criteria
|
||
|
||
**Functional Completeness:**
|
||
- ✅ Users can define team capacity
|
||
- ✅ Users can create projects with approved estimates
|
||
- ✅ Users can allocate resources month-by-month
|
||
- ✅ Users can log actual hours
|
||
- ✅ System validates allocations (over/under warnings)
|
||
- ✅ Users can view 5 core reports
|
||
- ✅ RBAC enforced (4 personas)
|
||
|
||
**Quality Metrics:**
|
||
- ✅ All tests passing (unit + E2E)
|
||
- ✅ Code coverage >70%
|
||
- ✅ Zero linting errors
|
||
- ✅ API documentation auto-generated
|
||
|
||
**Usability Metrics (Post-Launch):**
|
||
- Manager can complete monthly allocation in <30 minutes (vs 2+ hours in spreadsheet)
|
||
- Zero billing errors in first 3 months (over/under caught before invoicing)
|
||
- 90% of team members log actuals weekly
|
||
|
||
**AI Rationale:** "Fair but not too lenient. Manager time savings is measurable. Billing error prevention is critical. Adoption (90%) is achievable but requires discipline."
|
||
|
||
---
|
||
|
||
## Appendix: Conversation Highlights
|
||
|
||
### Most Insightful Moments
|
||
|
||
**On Under-Forecasting:**
|
||
> "Not OK. Because this money is my salary! We always try to be on par - 100%. If it is under-forecast, call that out."
|
||
|
||
**On Naming:**
|
||
> "Headroom. It's the word managers actually say ('do we have headroom for this?'), it immediately signals capacity planning, and it's memorable without being try-hard."
|
||
|
||
**On Caching:**
|
||
> "Query caching and Response caching on Redis from Day 1. No need to sweat on refactoring it everywhere."
|
||
|
||
**On Quality:**
|
||
> "I know this will be a time taking process. But I believe it will be worth it."
|
||
|
||
**On Final Review:**
|
||
> "Now this is the part I am most scared about. If I say yes, we need to stick to this rule book. Did I forget anything?"
|
||
|
||
### Your Leadership Style
|
||
|
||
**Observations from conversation:**
|
||
- **Pragmatic:** Willing to defer features to keep scope tight
|
||
- **Quality-focused:** Insisted on testing, code review, coverage from day 1
|
||
- **Deliberate:** Paused multiple times to verify decisions before committing
|
||
- **Learning-oriented:** Chose SvelteKit despite unfamiliarity, trusted AI recommendations on unfamiliar tools (TanStack Table)
|
||
- **Business-minded:** Constantly connected technical decisions to business impact (billing accuracy, manager time savings)
|
||
|
||
---
|
||
|
||
## Next Steps (Post-Documentation)
|
||
|
||
### Immediate Actions
|
||
|
||
1. **Review Documentation**
|
||
- Read Project Charter
|
||
- Review Architecture Document
|
||
- Verify Decision Log captures everything
|
||
|
||
2. **Formalize in OpenSpec**
|
||
- Create first change: `/opsx-new headroom-foundation`
|
||
- Document proposal, specs, design, tasks
|
||
- Begin implementation
|
||
|
||
3. **Project Setup**
|
||
- Initialize Laravel project
|
||
- Initialize SvelteKit project
|
||
- Create Docker Compose setup
|
||
- Configure PostgreSQL + Redis
|
||
|
||
4. **First Sprint (Week 1)**
|
||
- Database schema design
|
||
- Docker Compose working
|
||
- JWT authentication
|
||
- Basic CRUD for team members
|
||
|
||
---
|
||
|
||
**Document Control:**
|
||
- **Owner:** Santhosh J
|
||
- **Type:** Conversation Archive & Decision Log
|
||
- **Purpose:** Comprehensive record for future reference
|
||
- **Intended Audience:** Santhosh J, Associate
|
||
- **Format:** Markdown (for git), Word (for hardcopy)
|
||
|
||
---
|
||
|
||
*"This is my magnum opus project as of date."* — Santhosh J, February 17, 2026
|
||
|
||
---
|
||
|
||
*End of Decision Log*
|