Spaces:
Running
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.
- Containerfile, Nginx, Supervisord, Uvicorn wired up and running
- Alembic migrations for all tables run at startup
- FastAPI routers:
/people,/projects,/allocations,/leaves,/reports,/users - React scaffold: sidebar navigation, page shell, routing
- HTTP Basic Auth + login page + sign out + session credentials
- Dashboard page: KPI cards and overallocation alerts
- People page: list + add / edit person form + skills assignment + archive
- Projects page: list / card view + add / edit project form
- Projects page: milestones add / edit / complete
- Schedule page: read-only allocation bars across people rows
- Schedule page: create / edit / delete allocations
- Leaves: log leave from People page (modal) and Schedule page (button)
- Public holidays admin from Settings page
- Toasts for success / error feedback
- 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
- Conflict detection and overallocation highlighting (red bars)
- Capacity page: heatmap grid with color coding
- Capacity page: capacity vs demand chart (totals per week)
- Projects page: Gantt-like view with milestone markers and today line
- Leave management: log leave from the People page and schedule view
- 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.
- Reports page: utilization table + chart
- Reports page: availability report
- Reports page: leave summary
- Reports page: overallocated report
- CSV export for all report types
- Settings page: user management
- Settings page: skill library
- 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)
- 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-datavolume): data persists; reload only when you choose to reset demo data
6. Local & container workflow
Local backend
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
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
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 and the Project Manager guide.
- Top-tab navigation (People · Projects · Schedule · Capacity · Reports · Manage)
- People Planner: weekly availability grid grouped by team / department
- Per-week cell shows free / Full / over hours with Runn color coding
- Aggregate row per team (collapsible)
- Sub-toolbar: search, group-by, sort, chart toggle, tentative toggle, range
- Date controls: « ‹ Today › » with month / quarter range selectors
- "+ New Person" inline action at the bottom of the planner
- Per-person weekly availability endpoint (
GET /api/v1/reports/people-weekly-availability) - 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.
- CORS origins configurable via
CORS_ORIGINSandCORS_ORIGIN_REGEXenv vars -
vercel.jsonat repo root buildingfrontend/ -
frontend/.env.exampledocumentingVITE_API_BASE_URL -
.github/workflows/ci.yml— type-check + build on PR / push -
.github/workflows/vercel-deploy.yml— production push, preview PR -
render.yamlblueprint for the backend container with persistent disk -
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.