Files
headroom/docs/headroom-decision-log.md
Santhosh Janardhanan 3e36ea8888 docs(ui): Add UI layout refactor plan and OpenSpec changes
- Update decision-log with UI layout decisions (Feb 18, 2026)
- Update architecture with frontend layout patterns
- Update config.yaml with TDD, documentation, UI standards rules
- Create p00-api-documentation change (Scribe annotations)
- Create p01-ui-foundation change (types, stores, Lucide)
- Create p02-app-layout change (AppLayout, Sidebar, TopBar)
- Create p03-dashboard-enhancement change (PageHeader, StatCard)
- Create p04-content-patterns change (DataTable, FilterBar)
- Create p05-page-migrations change (page migrations)
- Fix E2E auth tests (11/11 passing)
- Add JWT expiry validation to dashboard guard
2026-02-18 13:03:08 -05:00

34 KiB
Raw Blame History

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
  2. Requirements Discovery
  3. Technical Stack Decisions
  4. Architecture Decisions
  5. Quality & Testing Decisions
  6. Deferred Features
  7. Rejected Options
  8. Open Questions
  9. 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)

UI Layout Decisions

Date: February 18, 2026
Context: After initial authentication implementation, reviewed login page UI and decided to establish a comprehensive layout system.

Problem Statement

The initial UI implementation used a simple top-navbar pattern without a standardized layout system. For a data-dense resource planning application, this approach would not scale well.

Design Direction

Aesthetic Spectrum Decision:

  • Target: 70% Data-Dense | 30% Utilitarian
  • Reference Apps: Obsidian (minimal chrome, content-first) + Jira (hierarchical sidebar, dense tables)

Core Layout Decisions

Decision Choice Rationale
Sidebar Collapsible (full ↔ icons-only ↔ hidden) Preserves screen real estate for low-resolution displays; sidebar should not eat productive space
Month Selector Global (in top bar) Allocation and actuals views are month-centric; affects all views
Default Theme Light mode Starting simple; dark mode available as toggle
Icon Library Lucide Svelte Modern, more icon variety, consistent with Svelte ecosystem
UI Framework DaisyUI-first (no shadcn-svelte) Already have it, excellent for business apps, use ~80% of its potential
Navigation Pattern Persistent sidebar + top bar Obsidian/Jira style; sectioned navigation (Planning, Reports, Admin)

Sidebar Specifications

EXPANDED (240px)        COLLAPSED (64px)       HIDDEN (0px)
┌────────────────┐      ┌────────┐            ┌──────────────────┐
│ ◀ ▶            │      │ ▶      │            │                  │
│ ────────────── │      │ ────── │            │   Full width     │
│ PLANNING       │      │        │            │   content        │
│ 📊 Dashboard   │      │ 📊     │            │                  │
│ 👥 Team Mem    │      │ 👥     │            │   (toggle via    │
│ 📁 Projects    │      │ 📁     │            │    Cmd/Ctrl+\)   │
│ 📅 Allocations │      │ 📅     │            │                  │
│ ✅ Actuals     │      │ ✅     │            │                  │
│ ────────────── │      │ ────── │            │                  │
│ REPORTS        │      │        │            │                  │
│ 📈 Forecast    │      │ 📈     │            │                  │
│ 📉 Utilization │      │ 📉     │            │                  │
│ 💰 Costs       │      │ 💰     │            │                  │
│ 📋 Variance    │      │ 📋     │            │                  │
│ ────────────── │      │ ────── │            │                  │
│ ADMIN*         │      │        │            │                  │
│ ⚙️ Settings    │      │ ⚙️     │            │                  │
│ ────────────── │      │ ────── │            │                  │
│ 🌙 Dark [tgl]  │      │ 🌙     │            │                  │
└────────────────┘      └────────┘            └──────────────────┘

* Admin section visible only to superuser role

Responsive Behavior

Breakpoint Sidebar Behavior Toggle
≥1280px (xl) Expanded by default Manual toggle only
1024-1279px (lg) Collapsed by default Manual toggle only
768-1023px (md) Hidden (drawer overlay) Hamburger menu
<768px (sm) Hidden (drawer overlay) Hamburger menu

Implementation Approach

Phased Changes:

  1. p00-api-documentation — Add Scribe annotations to all controllers
  2. p01-ui-foundation — Types, stores, Lucide setup, theme system
  3. p02-app-layout — AppLayout, Sidebar, TopBar, Breadcrumbs
  4. p03-dashboard-enhancement — Dashboard with stat cards
  5. p04-content-patterns — DataTable, StatCard, FilterBar, EmptyState, LoadingState
  6. p05-page-migrations — Migrate remaining pages incrementally

Files to Create

frontend/src/lib/
├── types/layout.ts                    # SidebarState, NavItem, NavSection
├── stores/
│   ├── layout.ts                      # sidebarState, theme
│   └── period.ts                      # selectedMonth (global)
├── config/navigation.ts               # Navigation sections config
└── components/layout/
    ├── AppLayout.svelte               # Main layout wrapper
    ├── Sidebar.svelte                 # Collapsible navigation
    ├── TopBar.svelte                  # Search, month, user menu
    ├── Breadcrumbs.svelte             # Navigation context
    └── PageHeader.svelte              # Page title + actions

DaisyUI Table Density

View Classes
Allocation Matrix table-compact table-pin-rows table-pin-cols
Projects List table-zebra table-pin-rows
Team Members table-zebra
Reports table-compact table-pin-rows

Key Quotes from Discussion

"I like a collapsible sidebar, because some people use very low screen resolution which will limit the real estate to play around with. Sidebar should not eat up the productive space."

"Make [month selector] global."

"Light mode for now."

"I lean more towards data-dense. How about keeping it 30-70 (utilitarian-data-dense)?"

"Use Lucide."


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