resource-portal / SPEC.md
Gowrisankar
Update demo seed projects to Address Discovery, Hold IST, KTLO/Admin, Mainframe, and Pimcore PaaS.
473d9e5
# IT Resource Management Portal — Build Spec & Status
This is the working spec for the internal Resource Management Portal. It mirrors
`IT_Resource_Portal_Specs.docx` (v1.0, April 2026) and tracks progress phase by
phase. Update the checklist boxes (`- [ ]``- [x]`) as items ship and pass
testing.
> Reference document: `IT_Resource_Portal_Specs.docx` (Project Overview,
> Technology Stack, Container Architecture, Data Model, Pages & Workflows,
> Frontend Components, Backend Implementation, Build Phases, Configuration).
---
## 1. Stack snapshot
| Layer | Choice | Status |
| ---------------- | --------------------------------------- | ------ |
| Container | Podman, single image | Done |
| Process manager | Supervisord (Nginx + Uvicorn) | Done |
| Reverse proxy | Nginx (`/api/v1/*` → FastAPI on `:8000`)| Done |
| Frontend | React 18 + Vite + TypeScript | Done |
| State / data | Zustand (UI), TanStack Query (server) | Done |
| HTTP client | Axios with HTTP Basic interceptor | Done |
| Backend | FastAPI + Uvicorn | Done |
| ORM / DB | SQLAlchemy 2.0 + SQLite (WAL) | Done |
| Migrations | Alembic at startup | Done |
| Persistence | Podman volume `portal-data` → `/data` | Done |
| Auth | HTTP Basic (admin / manager / viewer) | Done |
---
## 2. Phase 1 — MVP
Goal: A working container with data persistence, basic CRUD for people and
projects, and the resource schedule view with manual allocation entry.
- [x] Containerfile, Nginx, Supervisord, Uvicorn wired up and running
- [x] Alembic migrations for all tables run at startup
- [x] FastAPI routers: `/people`, `/projects`, `/allocations`, `/leaves`, `/reports`, `/users`
- [x] React scaffold: sidebar navigation, page shell, routing
- [x] HTTP Basic Auth + login page + sign out + session credentials
- [x] Dashboard page: KPI cards and overallocation alerts
- [x] People page: list + add / edit person form + skills assignment + archive
- [x] Projects page: list / card view + add / edit project form
- [x] Projects page: milestones add / edit / complete
- [x] Schedule page: read-only allocation bars across people rows
- [x] Schedule page: create / edit / delete allocations
- [x] Leaves: log leave from People page (modal) and Schedule page (button)
- [x] Public holidays admin from Settings page
- [x] Toasts for success / error feedback
- [x] Empty states + loading skeletons on all primary pages
---
## 3. Phase 2 — Core Interactions
Goal: The schedule view becomes interactive. Capacity heatmap ships. Gantt view
ships.
- [ ] Drag-to-create on the schedule timeline
- [ ] Drag-to-resize on existing allocation bars
- [ ] Drag-to-move on existing allocation bars
- [x] Conflict detection and overallocation highlighting (red bars)
- [x] Capacity page: heatmap grid with color coding
- [x] Capacity page: capacity vs demand chart (totals per week)
- [x] Projects page: Gantt-like view with milestone markers and today line
- [x] Leave management: log leave from the People page and schedule view
- [x] Public holidays: admin can add dates that block capacity for all
---
## 4. Phase 3 — Reports & Polish
Goal: Reports, CSV export, settings page, and UX polish.
- [x] Reports page: utilization table + chart
- [x] Reports page: availability report
- [x] Reports page: leave summary
- [x] Reports page: overallocated report
- [x] CSV export for all report types
- [x] Settings page: user management
- [x] Settings page: skill library
- [x] Settings page: working week config (read-only display in v1)
- [ ] Person detail side panel with mini schedule and leave calendar
- [ ] Project detail side panel with team members and milestone list
- [ ] Responsive layout improvements (works on tablets)
- [x] Error states, empty states, loading skeletons on all pages
---
## 5. Backend endpoints (current surface)
All endpoints require HTTP Basic auth. Mutations require `manager` or `admin`
role; user management requires `admin`.
| Method | Path | Description |
| ------ | ----------------------------------------------- | ---------------------------------------------------------- |
| GET | `/api/v1/health` | Liveness check |
| GET | `/api/v1/me` | Current user (used by login) |
| GET | `/api/v1/dashboard` | KPIs + overallocations + upcoming milestones |
| GET | `/api/v1/people` | List active people (with skills) |
| POST | `/api/v1/people` | Create a person |
| GET | `/api/v1/people/{id}` | Get a person |
| PATCH | `/api/v1/people/{id}` | Update a person (incl. `skill_ids`) |
| DELETE | `/api/v1/people/{id}` | Archive (soft-delete) a person |
| GET | `/api/v1/people/{id}/availability?start&end` | Capacity for one person over a window |
| GET | `/api/v1/skills` | List skills |
| POST | `/api/v1/skills` | Create a skill |
| GET | `/api/v1/projects` | List active projects (with milestones) |
| POST | `/api/v1/projects` | Create a project |
| PATCH | `/api/v1/projects/{id}` | Update a project |
| DELETE | `/api/v1/projects/{id}` | Archive (soft-delete) a project |
| POST | `/api/v1/projects/{id}/milestones` | Add a milestone |
| PATCH | `/api/v1/projects/{id}/milestones/{milestoneId}`| Update a milestone |
| GET | `/api/v1/allocations?person_id&project_id&start&end` | List allocations |
| POST | `/api/v1/allocations` | Create an allocation (capacity-validated) |
| PATCH | `/api/v1/allocations/{id}` | Update an allocation |
| DELETE | `/api/v1/allocations/{id}` | Delete an allocation |
| GET | `/api/v1/leaves?person_id&start&end&leave_type` | List leave records |
| POST | `/api/v1/leaves` | Create a leave entry |
| PATCH | `/api/v1/leaves/{id}` | Update a leave entry |
| DELETE | `/api/v1/leaves/{id}` | Delete a leave entry |
| GET | `/api/v1/public-holidays?year` | List public holidays |
| POST | `/api/v1/public-holidays` | Create a public holiday |
| GET | `/api/v1/reports/utilization?start&end` | Utilization per person |
| GET | `/api/v1/reports/capacity?start&end` | Aggregate capacity per week |
| GET | `/api/v1/reports/availability?start&end` | Available hours per person |
| GET | `/api/v1/reports/overallocated?start&end` | People > 100% utilized |
| GET | `/api/v1/reports/project-allocation?start&end` | Allocations broken out by project |
| GET | `/api/v1/users` | List portal users |
| POST | `/api/v1/users` | Create a user |
| GET | `/api/v1/admin/seed-demo/status` | Whether portal DB is empty (admin only) |
| POST | `/api/v1/admin/seed-demo?replace=true` | Wipe portal data (except users) and load sample IT dataset |
Set `ENABLE_DEMO_DATA=false` on the office Linux box to hide and disable these endpoints in production.
### Sample / demo data (testing)
Admin-only fictional dataset for exploring the portal (similar to Runn’s trial explore flow):
- **7 people**, **5 projects** (Address Discovery, Hold IST, KTLO/Admin, Mainframe, Pimcore PaaS), roles, teams, skills, allocations (including one overallocated person), leaves, and public holidays
- **Insights** (empty portal): “Load sample data” button with confirmation
- **Manage → Users**: “Load sample data” / “Reload sample data”
- **Hugging Face Spaces**: database is ephemeral — reload sample data after each deploy
- **Office Podman** (`portal-data` volume): data persists; reload only when you choose to reset demo data
---
## 6. Local & container workflow
### Local backend
```bash
cd backend
python3 -m venv .venv
source .venv/bin/activate
pip install -r requirements.txt
ADMIN_PASSWORD=admin uvicorn main:app --reload
```
API docs: `http://localhost:8000/docs`.
### Local frontend
```bash
cd frontend
npm install
npm run dev
```
The frontend proxies `/api/v1/*` to the local backend. The login page collects
the credentials at runtime — no `VITE_ADMIN_*` env vars are required.
### Container
```bash
podman volume create portal-data
podman build -t resource-portal .
podman run -d --replace -p 8080:80 -v portal-data:/data --name portal \
-e ADMIN_USERNAME=admin \
-e ADMIN_PASSWORD=admin \
resource-portal
```
Open `http://localhost:8080` and sign in with the admin credentials. The portal
starts empty — use **Insights → Load sample data** (admin) or add data manually
from **Manage → People** and **Manage → Projects**.
---
## 7. Phase 4 — Runn-style planner parity
Inspired by [Runn’s People Planner](https://help.runn.io/en/articles/5185963-set-up-your-runn-account)
and the [Project Manager guide](https://help.runn.io/en/articles/8273502-a-guide-for-project-managers).
- [x] Top-tab navigation (People · Projects · Schedule · Capacity · Reports · Manage)
- [x] People Planner: weekly availability grid grouped by team / department
- [x] Per-week cell shows free / Full / over hours with Runn color coding
- [x] Aggregate row per team (collapsible)
- [x] Sub-toolbar: search, group-by, sort, chart toggle, tentative toggle, range
- [x] Date controls: « ‹ Today › » with month / quarter range selectors
- [x] "+ New Person" inline action at the bottom of the planner
- [x] Per-person weekly availability endpoint (`GET /api/v1/reports/people-weekly-availability`)
- [x] Runn-flavored purple/lavender visual language
- [ ] Project Planner — assignments grouped under each project
- [ ] Drag-to-create / resize / move on planner cells
- [ ] Time-off display mode and "Bulk add" assignments
- [ ] Phases on projects and milestone diamonds in the planner row
- [ ] Project budget tracker and dashboard view
- [ ] Custom fields for people and projects
## 8. Hosted deployment workflow
See `DEPLOY.md` for the full step-by-step guide.
- [x] CORS origins configurable via `CORS_ORIGINS` and `CORS_ORIGIN_REGEX` env vars
- [x] `vercel.json` at repo root building `frontend/`
- [x] `frontend/.env.example` documenting `VITE_API_BASE_URL`
- [x] `.github/workflows/ci.yml` — type-check + build on PR / push
- [x] `.github/workflows/vercel-deploy.yml` — production push, preview PR
- [x] `render.yaml` blueprint for the backend container with persistent disk
- [x] `DEPLOY.md` — switching git remote, secrets, day-to-day workflow
- [ ] First production deploy executed (Vercel + Render URLs captured)
- [ ] Custom domain wired up on Vercel (optional)
## 10. Open follow-ups
- Drag-and-drop on the planner (Phase 2 / Runn parity).
- Right-side detail panels for People and Projects (Phase 3 polish).
- Responsive tablet breakpoints below 1024px.
- OAuth2 / SSO upgrade path is explicitly v2 territory and out of scope here.