Version: 1.0 Status: Approved for M5 freeze Last updated: 2026-05-21
Loopless is the freelancer–enterprise collaboration platform where work itself becomes the portfolio. Static profiles and keyword job boards are replaced by GitHub-integrated project pages, semantic skill matching via vector embeddings, asynchronous standups that eliminate meeting overhead, and AI-generated project summaries that reduce status-check load to a single click.
| Quarter | Focus | Outcome |
|---|---|---|
| Q2 2026 | Capstone MVP (this doc) | 200 simulated users, A/B-validated onboarding, demo-ready stack |
| Q3 2026 | Public beta | 50 paying enterprises, 500 freelancer signups, 100 paid projects |
| Q4 2026 | Marketplace economics | Escrow, milestones, dispute resolution, Stripe Connect payouts |
| Q1 2027 | Scale | Mobile native (React Native), multi-region deploys, gRPC for AI streaming, MongoDB document store for unstructured artifacts |
- Semantic match accuracy — pgvector cosine similarity ranked against keyword search on the same dataset. Target uplift: ≥30% match relevance (manually labelled holdout).
- Live project transparency — GitHub commit sync + AI summaries lower the cost of trust for enterprises evaluating freelancer work.
- Async-first collaboration — standup data becomes a first-class feature, feeding sentiment NLP and reducing meeting hours.
- AI-native ops — RAG summaries, semantic search, sentiment NLP, AIOps alert triage. Treat AI as an operating system, not a feature.
The freelance economy is projected to exceed $12 trillion globally by 2030. Despite scale, friction remains high:
| Pain | Evidence | Cost |
|---|---|---|
| Generic matching | Upwork/Fiverr/Freelancer.com return keyword-matched profiles ignoring semantic skill context | Enterprises trial multiple freelancers; freelancers spend hours customizing proposals |
| Opaque progress | Status updates live in Slack, Drive, email, repos — no single source of truth | Enterprises micromanage or wait for weekly digests |
| Meeting overhead | Sync standups across time zones cost 2–4 hr/week per pair | Burnout; throughput loss |
| Platform fees | Upwork/Fiverr 20% tiered; Toptal premium | Erodes freelancer take-home |
Loopless attacks matching, transparency, and meetings. Fee competition is a downstream lever once the funnel works.
- Demographics: 32, Berlin, 8 years experience, $90/hr blended rate
- Tools today: Upwork (lead-gen), GitHub (work), Slack (clients), Notion (proposals)
- Goals: Quality engagements ≥3 months; reduce time spent prospecting; show live work artifacts to win without unpaid sample tasks
- Frustrations: Generic Upwork matches; clients ghost; static portfolio bit-rot
- Loopless win: Connect GitHub once → live project pages auto-update → AI summaries close enterprises in a single async loop
- Demographics: 38, Austin, runs a 12-person backend team, ~$200k contractor budget/quarter
- Tools today: Toptal (vetted freelancers), Linear (work), GitHub (code review), Calendly (interviews)
- Goals: Find specialized freelancers fast (e.g., Postgres internals, Kubernetes operator dev) without 5-round interviews
- Frustrations: Toptal vetting is slow; freelancer status visibility is opaque post-hire; weekly status calls eat his calendar
- Loopless win: Semantic search finds matches in minutes; standup timeline replaces calls; AI summary on demand for stakeholder updates
- Demographics: Loopless ops staff
- Goals: Keep platform healthy, detect abuse, A/B-test growth experiments
- Tools: Admin dashboard, PostHog, Grafana, feature flags
- Loopless win: Single admin pane with user mgmt, feature flags, AARRR funnel + retention dashboards
| ID | Use case | Primary persona | Happy path | Critical edge case |
|---|---|---|---|---|
| UC-1 | Sign up via GitHub | Mira | OAuth → Keycloak → role select → proficiencies → discover | GitHub OAuth denied → fallback email signup |
| UC-2 | Enterprise onboarding | Alex | Company details → hiring needs → categories → confirm | Validation failure on website URL → inline error, no data loss |
| UC-3 | Semantic discovery | Alex | /discover ranks freelancers by cosine sim against company embeddings |
OpenAI embed API down → stub fallback EmbeddingService |
| UC-4 | Create project + link GitHub | Mira | Title, description, repo URL → save → Hangfire job pulls 50 commits within 30 min | GitHub rate limit hit → exponential backoff in job |
| UC-5 | Generate AI summary | Alex | Open project → click "Generate Summary" → RAG retrieves commits + files + links → OpenAI returns summary in 5–15s | OpenAI timeout → display previous cached summary + retry button |
| UC-6 | Submit standup | Mira | Project page → 3-question form → SignalR pushes notification to enterprise | Already submitted today → show today's entry, lock form |
| UC-7 | Real-time DM | Mira ↔ Alex | Open conversation → type → SignalR delivers within 2s; typing indicators | WebSocket fails → long-polling fallback transport |
| UC-8 | Invite freelancer | Alex | Project detail → Invite → freelancer notification → accept/decline | Freelancer suspended → invitation hidden |
| UC-9 | Upload project file | Mira | Drag/drop → multipart to S3 → signed URL on detail page | File >25MB → client + server rejection with clear message |
| UC-10 | Admin user suspension | Sam | User list → suspend → audit trail entry → user logged out next refresh | Cannot suspend last admin → guarded by role policy |
Full epic coverage in user-stories.md (~300 stories, RICE/MoSCoW prioritized).
- FR-1.1: Keycloak 25 identity provider, GitHub OAuth2 SSO
- FR-1.2: JWT access (15 min) + refresh tokens (7 days)
- FR-1.3: RBAC with three roles (Freelancer, Enterprise, Admin) enforced backend + frontend
- FR-1.4: Token refresh middleware with 401 queue on frontend
- FR-2.1: Role selection with persisted Zustand store
- FR-2.2: Freelancer flow: proficiencies → confirmation (Zod-validated)
- FR-2.3: Enterprise flow: details → hiring needs → categories → confirmation
- FR-2.4: Pgvector embeddings generated post-onboarding via
EmbeddingGenerationJob
- FR-3.1: Cosine-similarity ranked feed in
GET /api/v1/matching/discover - FR-3.2: Semantic search via
GET /api/v1/matching/search?q=... - FR-3.3: Filters: proficiency, availability, rate range, industry
- FR-3.4: Real-time
NewMatchpush via SignalR on profile updates
- FR-4.1: Project CRUD with soft delete and audit trail
- FR-4.2: GitHub commit sync via Hangfire every 30 min (rate-limit-aware)
- FR-4.3: File upload (multipart) to S3/MinIO, max 25MB, formats: PDF, DOCX, PNG, JPG, ZIP
- FR-4.4: Project links (URL + title + description)
- FR-4.5: RAG-generated summaries cached in
ProjectSummariestable, history retained - FR-4.6: Invitation system (enterprise → freelancer or vice versa) with accept/decline
- FR-4.7: Project visibility default
invited-only, enforced backend
- FR-5.1: Toggle per project
- FR-5.2: Three required fields (did / will / blockers); one per freelancer per project per day
- FR-5.3: Timeline view reverse chronological, filterable by date
- FR-5.4:
BlockerDetectionJobNLP sentiment daily; flag at-risk projects - FR-5.5: Notification on submit via RabbitMQ →
StandupNotificationConsumer→ SignalR
- FR-6.1: Real-time DMs via SignalR
MessagingHubwith Redis backplane - FR-6.2: Typing indicators (
StartTyping/StopTyping) - FR-6.3: Conversation list with unread counts
- FR-6.4: File sharing in messages (reuses project file upload pipeline)
- FR-6.5: Email digest for unread >5 min via MailKit + Hangfire
- FR-7.1: User mgmt: list, filter, suspend (soft delete), audit log
- FR-7.2: Feature flags via
.NET FeatureManagement - FR-7.3: Analytics dashboard: total users, projects, messages, standups (weekly/monthly)
- FR-8.1: Embeddings via OpenAI
text-embedding-ada-002(1536-dim, pgvector IVFFlatlists=100) - FR-8.2: Embeddings regenerated on profile/project change via
EmbeddingGenerationJob - FR-8.3: RAG summaries: retrieve commits + file extracts + link metadata → chat completion
- FR-8.4: Sentiment NLP on standup blockers via
NlpService
| Metric | Target | Current (Sprint 4) |
|---|---|---|
| Lighthouse Performance (all routes) | ≥90 | 99 avg |
| Lighthouse Accessibility | ≥90 | passing |
| API p95 latency | <200ms | in progress (k6) |
| Frontend FCP | <500ms | <400ms |
| Frontend LCP | <1500ms | <1200ms |
| CLS | <0.05 | 0.005 |
- SLO: 99% monthly uptime for public surface
- Health checks on every dependency (Postgres, Redis, RabbitMQ, Keycloak, external APIs)
- Uptime Kuma probes every 60s + status page
- Hangfire retry policy: exponential backoff, dead-letter after 5 failures
- RabbitMQ topic exchange with DLQ for failed event processing
- All endpoints behind Keycloak JWT except
/auth/*and/health/* - Rate limiting: 60 req/min global, 10/min auth, 5/min AI, 30/min matching
- Input validation via FluentValidation on every command/query
- Soft deletes + AuditTrails for compliance
- Secrets in Azure Key Vault / GCP Secret Manager (no plaintext in repo or images)
- Trivy CVE scan + git-secrets + truffleHog in CI
- OWASP ZAP baseline scan (manual + weekly cron)
- Sensitive-data destructuring in Serilog logs (PII redaction)
- WCAG 2.1 AA accessibility compliance (axe DevTools passing)
- Stateless API; horizontal pod autoscaling via K8s HPA
- SignalR Redis backplane for multi-replica WebSocket fan-out
- Postgres connection pooling via Npgsql
- pgvector IVFFlat index tuned for ~100k profiles
- Hangfire workers separable into dedicated pods if AI load grows
- Clean Architecture (Domain → Application → Infrastructure → API), no cross-layer imports
- CQRS via MediatR with
ValidationBehavior+LoggingBehaviorpipelines - Centralized NuGet versions in
Directory.Packages.props - Conventional Commits + release-please semantic versioning
- 70%+ backend test coverage; Playwright covers core flows
- Single-command dev environment via Docker Compose profiles
WAMP — Weekly Active Matched Pairs: number of unique (freelancer, enterprise) pairs with at least one commit sync, file upload, standup entry, or message exchange in a calendar week.
| Stage | Metric | M5 target |
|---|---|---|
| Acquisition | Signups/week | 50 (simulated load test) |
| Activation | % completing onboarding | ≥80% |
| Retention | D7 return rate | ≥40% |
| Referral | Invitations/user | ≥1.5 |
| Revenue | Paid project starts | n/a (capstone) |
Full breakdown in north-star-metric.md. Tracking implemented via PostHog + Hangfire AnalyticsRollupJob.
See okrs.md. Headline:
- O1: Ship a capstone-grade platform that demos end-to-end on demo day
- O2: Prove semantic matching beats keyword search on labelled holdout
- O3: Document AI-assisted development as a reusable playbook
- 4 team members + 3 instructors
- Run scripted enterprise + freelancer walkthroughs (
devops/scripts/enterprise-walkthrough.py,freelancer-walkthrough.py) - Collect feedback via in-app survey + sentiment NLP on free-text
- Live 15-min demo against the deployed stack
- 10-min technical deep-dive
- 5-min AI retrospective
- Q&A with instructors
- Open signup with 10-enterprise allowlist
- Stripe Connect onboarding (out of scope for M5)
- Feature flags control gradual rollout per cohort
- Payments / escrow / milestones (Q4 2026)
- Mobile native apps (Q1 2027)
- Contract templates / e-signature
- Dispute resolution workflow
- Time tracking / invoicing
- Calendar integration / scheduling
- Video calls (deliberately — async-first)
- Multi-language i18n (English only)
- gRPC streaming for AI (potential +2% bonus, deferred)
- MongoDB secondary store (potential +2% bonus, deferred)
| Risk | Probability | Impact | Mitigation |
|---|---|---|---|
| GitHub rate limit hits during demo | Medium | Medium | Cached commits in GitHubCommits table; conditional ETag requests |
| OpenAI cost overrun | Medium | High | Token limits per request, cached summaries, stub fallback for embeddings |
| Keycloak config drift between dev/prod | High | High | Realm exported to devops/keycloak/loopless-realm.json, auto-imported |
| Scope creep | High | Critical | Strict MVP boundary, weekly scope review, parking-lot doc |
| Demo-day stack flake | Medium | High | Pre-recorded fallback demo, k6 warm-up before live demo |
| AI summary hallucination on sparse data | Medium | Medium | Prompt enforces "respond only from provided context"; UI shows source artifacts |
Open questions (escalate to instructor):
- Should multi-tenancy guarantees be hardened beyond
enterprise_idfilter pattern before M5? - Is gRPC streaming worth pursuing for +2% bonus given 8-day window?