8.0 KiB
Sequence Diagram
Metadata
| Key | Value |
|---|---|
| ID | SD-001 |
| CrossReference | OC-001, DCD-001 |
Version History
| Date | Status | Author | Reviewer | Change | Commit |
|---|---|---|---|---|---|
| 2026-10-06 | Deprecated | Jens Tirsvad Nielsen | S02 | Messages aligned with the method signatures of DCD-001 Cited DCD-001 |
f4d611b |
| 2026-10-06 | Accepted | Jens Tirsvad Nielsen | S02 | Added CredentialCollector and EnvFileWriter and their messages (P2, P14) | ded26a6 |
Design objects are conceptual; in create-project.sh each becomes a small function group. DCD-001 gives each object its class and turns each message below into a method signature.
Sequence: startProjectCreation
Realizes: startProjectCreation in OC-001
Diagram
@startuml
actor Maintainer
participant ":ProjectCreator" as PC
participant ":ConfigLoader" as CL
participant ":ToolChecker" as TC
participant ":CredentialCollector" as CC
Maintainer -> PC : startProjectCreation()
activate PC
create CL
PC -> CL : load(config.env, .env)
activate CL
CL --> PC : configuration
deactivate CL
create CC
PC -> CC : collect(configuration, GITEA_TOKEN)
activate CC
CC --> PC : configuration
deactivate CC
create TC
PC -> TC : check(git, curl, jq)
activate TC
TC --> PC : toolCheck
deactivate TC
PC --> Maintainer : promptSet
deactivate PC
destroy CL
destroy CC
destroy TC
@enduml
Pattern Annotations
| Pattern (GRASP / GoF) | Applied to | Rationale |
|---|---|---|
| Controller (GRASP) | ProjectCreator |
Receives the system operations and coordinates, without doing the work itself |
| Pure Fabrication (GRASP) | ConfigLoader, ToolChecker, CredentialCollector |
No domain concept owns parsing, tool checks or asking for a credential; separate small units keep cohesion high |
| Creator (GRASP) | ConfigLoader creates Configuration |
It holds the data needed to build and validate it |
Postcondition Coverage
| Postcondition (from contract) | Satisfied by message |
|---|---|
| P1 Run created | startProjectCreation received by ProjectCreator |
| P2 Configuration created and validated; a missing credential entered, validated and held in memory | load(config.env, .env) and collect(configuration, GITEA_TOKEN) |
| P3 ToolCheck created | check(git, curl, jq) |
| P4 PromptSet returned | promptSet return to the Maintainer |
Responsibility Check
ProjectCreator only sequences three calls; parsing and validation sit in ConfigLoader, asking for a missing credential in CredentialCollector, tool detection in ToolChecker. No object receives every message. Project details preset in config.env are read and validated by ConfigLoader as part of configuration; the second sequence is unchanged, because provideProjectDetails receives the same arguments whether they were asked or preset.
Sequence: provideProjectDetails
Realizes: provideProjectDetails in OC-001
Diagram
@startuml
actor Maintainer
participant ":ProjectCreator" as PC
participant ":Preflight" as PF
participant ":GiteaClient" as GT
participant ":GitHubClient" as GH
participant ":LocalProjectBuilder" as LB
participant ":FrameworkInstaller" as FI
participant ":SummaryReport" as SR
participant ":CredentialCollector" as CC
participant ":EnvFileWriter" as EW
Maintainer -> PC : provideProjectDetails(name, description, visibility, giteaOwner, githubOwner, directory, enablePlanGate, writeEnvFile)
activate PC
create GT
PC -> GT : new(configuration)
opt githubOwner present
create GH
PC -> GH : new(configuration)
end
opt githubOwner present
create CC
PC -> CC : collect(configuration, GITHUB_PAT, GITHUB_USER)
activate CC
CC --> PC : configuration
deactivate CC
end
create PF
PC -> PF : check(request)
activate PF
PF -> GT : verifyToken(), ownerAccepts(giteaOwner), nameFree(name), hasLicense(AGPL-3.0)
opt githubOwner present
PF -> GH : verifyToken(), ownerAccepts(githubOwner), nameFree(name)
end
PF --> PC : preflightResult
deactivate PF
opt githubOwner present
PC -> GH : createEmptyRepository(request)
activate GH
GH --> PC : gitHubRepository
deactivate GH
end
alt githubOwner present
PC -> GT : createRepository(request, license=AGPL-3.0)
else no GitHub
PC -> GT : createRepository(request, license=none)
end
activate GT
GT --> PC : giteaRepository
deactivate GT
opt githubOwner present
PC -> GT : addPushMirror(giteaRepository, gitHubRepository)
activate GT
GT -> GT : requestSync(pushMirror)
GT --> PC : pushMirror
deactivate GT
end
create LB
PC -> LB : build(directory, giteaRepository, gitHubRepository, sshPassed)
activate LB
LB --> PC : localProject (remotes origin, github)
deactivate LB
create FI
PC -> FI : install(localProject, enablePlanGate)
activate FI
FI --> PC : installResult
deactivate FI
opt writeEnvFile
create EW
PC -> EW : write(localProject, configuration, githubOwner present)
activate EW
EW --> PC : envFile
deactivate EW
end
create SR
PC -> SR : compose(request)
SR --> PC : summary
PC --> Maintainer : summary
deactivate PC
destroy PF
destroy GT
destroy GH
destroy LB
destroy FI
destroy CC
destroy EW
destroy SR
@enduml
Pattern Annotations
| Pattern (GRASP / GoF) | Applied to | Rationale |
|---|---|---|
| Controller (GRASP) | ProjectCreator |
Single entry for the system operation; sequences the steps and stops on the first failure |
| Pure Fabrication (GRASP) | Preflight, LocalProjectBuilder, FrameworkInstaller, SummaryReport, CredentialCollector, EnvFileWriter |
Each groups one responsibility that no domain concept owns |
| Facade (GoF) | GiteaClient, GitHubClient |
Hide each host's HTTP API and credential handling behind a small interface; tokens never leave them |
| Protection from variations (GRASP) | Client classes | The github-optional and license variations are decided by the controller's alt and opt, not inside the clients |
Postcondition Coverage
| Postcondition (from contract) | Satisfied by message |
|---|---|
| P1 ProjectRequest created | provideProjectDetails received by ProjectCreator |
| P2 PreflightResult created | check(request) |
| P3 GiteaRepository created | createRepository(request, license) |
| P4 LicenseFile when GitHub chosen, otherwise empty | createRepository(..., license=AGPL-3.0) and the alt branch license=none |
| P2 GitHub credentials known before the first request | collect(configuration, GITHUB_PAT, GITHUB_USER) inside opt githubOwner present |
| P5 empty GitHubRepository when chosen | createEmptyRepository(request) |
| P6 PushMirror and first sync | addPushMirror(...) and requestSync(pushMirror) |
| P7 LocalProject created, history from Gitea when not empty | build(directory, ...) |
| P8 origin remote (SSH if the test passed, else HTTPS) | build(..., sshPassed) |
| P9 github remote when chosen | build(...) |
| P10 framework Submodule | install(localProject, ...) |
| P11 HookSetup, plan gate if chosen | install(localProject, enablePlanGate) |
| P12 AGENTS.md and registry copied or kept | install(...) returning templates |
| P13 Summary created and returned | compose(request) and the final return |
| P14 EnvFile created with the needed credentials, owner-only, ignored by git, or none when declined | write(localProject, configuration, githubOwner present) inside opt writeEnvFile |
Responsibility Check
ProjectCreator sequences and decides on the optional paths but performs no HTTP, git or file work. Host calls are in the two clients, local work in LocalProjectBuilder and FrameworkInstaller, the credential prompts in CredentialCollector, the .env in EnvFileWriter, reporting in SummaryReport, so cohesion stays high and no object receives all messages. Failure handling (exceptions in OC-001) is the controller's single stop-and-report rule and is not drawn.