Plan: MT-4 — TenantConfig Interfaces + TenantConfigService#
Summary#
Create TenantConfig and RepoConfig interfaces plus a TenantConfigService that models all currently hardcoded configuration (org, labels, branch naming, LLM settings) as a typed object. Single-tenant implementation reads from ConfigService with hardcoded defaults. No existing files are modified.
Files#
| File | Action | Description |
|---|---|---|
src/tenant/tenant-config.interface.ts | create | TenantConfig and RepoConfig interfaces |
src/tenant/tenant-config.service.ts | create | TenantConfigService with getConfig() returning single tenant config from ENV + defaults |
src/tenant/tenant.module.ts | create | NestJS module providing and exporting TenantConfigService |
src/tenant/tenant-config.service.spec.ts | create | Unit tests for defaults, ConfigService reads, label values, missing required vars |
Steps#
- Create
TenantConfiginterface capturing:tenantId,org,platform,platformCredentialPath,botUsername,defaultBaseBranch,branchPrefix,labels(in-refinement, refined, in-review, agent-blocked, backlog),projectId,projectNumber,llmProvider,llmCredentialPath,llmModel,llmTimeoutSecs,defaultDirective. CreateRepoConfigextendingPartial<TenantConfig>withrepoandexcludeFromAgent. - Create
TenantConfigServiceinjectingConfigService. ImplementgetConfig(org?: string, repo?: string): TenantConfigthat readsGITHUB_OWNER,AGENT_USERNAME(required),PROJECT_ID,PROJECT_NUMBER,CLAUDE_TIMEOUT_SECS(optional with defaults) fromConfigService. Hardcode:platform='github',platformCredentialPath='env://GITHUB_TOKEN',defaultBaseBranch='master',branchPrefix='feat',llmProvider='claude-cli',defaultDirective='auto', label defaults matching current values ingithub.adapter.ts. - Add constructor validation: throw if
GITHUB_OWNERorAGENT_USERNAMEis missing/empty fromConfigService. - Create
TenantModuleproviding and exportingTenantConfigService, importingConfigModule. - Write unit tests: correct defaults, ConfigService reads for org/project/bot/timeout, label values match hardcoded strings, throws on missing required vars.
Verification#
npx tsc --noEmitpasses with no errorsnpm run lintpasses with zero warningsnpm run test -- --testPathPattern=tenant— all tests green
Risks#
- Label string drift: Hardcoded label values (
'in-refinement','agent-blocked', etc.) are duplicated fromgithub.adapter.ts. Future work (downstream issues) should centralize label references throughTenantConfigService.