Skip to content

Feature/unified entity schema docs - #155

Closed
marlon-costa-dc wants to merge 3 commits into
mainfrom
feature/unified-entity-schema-docs
Closed

Feature/unified entity schema docs#155
marlon-costa-dc wants to merge 3 commits into
mainfrom
feature/unified-entity-schema-docs

Conversation

@marlon-costa-dc

Copy link
Copy Markdown
Collaborator

No description provided.

…atterns

Address review comments from Qodo:
- Fix tenant scoping: add org_id to ProjectRepository trait (row-level isolation)
- Fix file paths: ports in mcb-domain not mcb-application, providers use database/ layout
- Fix schema example: use canonical table!/col!/index!/fk!/unique! macros
- Include all real fields: org_id, path, updated_at in entity and schema
- Add indexes, foreign_keys, unique_constraints to schema example
@coderabbitai

coderabbitai Bot commented Jul 27, 2026

Copy link
Copy Markdown

Warning

Review limit reached

@marlon-costa-dc, you've reached your PR review limit, so we couldn't start this review.

Next review available in: 41 minutes

Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available.
You're only billed for reviews past your plan's rate limits ($0.25/file).

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 95956615-0c98-4570-9e7c-0c11bc7e1495

📥 Commits

Reviewing files that changed from the base of the PR and between 507b04a and 772a5d6.

📒 Files selected for processing (1)
  • docs/architecture/CLEAN_ARCHITECTURE.md
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feature/unified-entity-schema-docs

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@gemini-code-assist

Copy link
Copy Markdown
Contributor

Caution

The consumer version of Gemini Code Assist on GitHub has been sunset. All code review activity has officially ceased.

@qodo-code-review

qodo-code-review Bot commented Jul 27, 2026

Copy link
Copy Markdown
Contributor

PR Summary by Qodo

Document clean architecture and unified domain schemas

📝 Documentation 🕐 10-20 Minutes

Grey Divider

AI Description

• Expands the clean architecture guide with layer responsibilities and dependency rules.
• Documents provider, service, and port extension patterns across workspace crates.
• Adds a tenant-scoped Project example using canonical domain schema metadata.
Diagram

graph TD
  APP["Application Services"] --> PORT["Repository Port"] --> ENTITY["Project Entity"]
  SCHEMA["Canonical Schema"] --> DDL["DDL Generator"] --> DB[("Database")]
  ADAPTER["Provider Adapter"] --> PORT
  ADAPTER --> ENTITY
  ADAPTER --> DDL
Loading
High-Level Assessment

The following are alternative approaches to this PR:

1. Extend the architecture SSOT
  • ➕ Keeps architectural guidance centralized in ARCHITECTURE.md
  • ➕ Avoids duplicating layer definitions and dependency rules
  • ➕ Reduces the risk of documentation drift
  • ➖ Makes the existing comprehensive architecture document longer
  • ➖ The unified model example may be less discoverable
2. Create a focused unified-model guide
  • ➕ Keeps the before-and-after example focused and independently discoverable
  • ➕ Preserves CLEAN_ARCHITECTURE.md as a stable link target
  • ➕ Allows detailed schema guidance without duplicating the full architecture
  • ➖ Introduces another architecture document to maintain
  • ➖ Requires clear cross-links from canonical documentation

Recommendation: Prefer adding the unified entity/schema/port pattern to the existing architecture SSOT or a dedicated linked guide, while retaining CLEAN_ARCHITECTURE.md as a concise stable entry point. Replacing that entry point with a second comprehensive architecture description duplicates existing material and increases drift risk.

Files changed (1) +620 / -17

Documentation (1) +620 / -17
CLEAN_ARCHITECTURE.mdExpand clean architecture and unified schema guidance +620/-17

Expand clean architecture and unified schema guidance

• Replaces the short architecture index with a comprehensive description of six layers, dependency direction, responsibilities, and extension workflows. Adds a before-and-after Project model demonstrating canonical domain entities, schema macros, tenant-scoped repository ports, constraints, and provider-side persistence mapping.

docs/architecture/CLEAN_ARCHITECTURE.md

@qodo-code-review

qodo-code-review Bot commented Jul 27, 2026

Copy link
Copy Markdown
Contributor

Code Review by Qodo

🐞 Bugs (7) 📘 Rule violations (0) 📜 Skill insights (0)

Context used
✅ Compliance rules (platform): 36 rules

Grey Divider


Action required

1. Nonexistent application layer 🐞 Bug ⚙ Maintainability ⭐ New
Description
The layer model assigns services and registries to an mcb-application crate that is not a
workspace member, so contributors cannot place or import code as documented. The actual seven-crate
workspace includes mcb-utils and mcb-validate, which this model omits.
Code

docs/architecture/CLEAN_ARCHITECTURE.md[R24-26]

+│ Layer 4: Application Services & Use Cases                   │
+│ (orchestration, business logic, registry)                   │
+│ Crate: mcb-application                                      │
Relevance

⭐⭐⭐ High

Documentation names a nonexistent crate and contradicts the seven-crate workspace.

PR-#57

ⓘ Recommendations generated based on similar findings in past PRs

Evidence
The workspace manifest lists all seven members without mcb-application, while the canonical
boundary guide assigns the actual layers and includes both utilities and validation tooling.

Cargo.toml[1-11]
docs/architecture/ARCHITECTURE_BOUNDARIES.md[54-74]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
The architecture model introduces a nonexistent `mcb-application` crate while omitting actual workspace crates. Update the document to use the repository's real crate ownership and dependency structure.

## Issue Context
The workspace and boundary documentation define seven crates: `mcb`, `mcb-utils`, `mcb-domain`, `mcb-providers`, `mcb-infrastructure`, `mcb-server`, and `mcb-validate`.

## Fix Focus Areas
- docs/architecture/CLEAN_ARCHITECTURE.md[6-46]
- docs/architecture/CLEAN_ARCHITECTURE.md[229-267]
- Cargo.toml[1-11]
- docs/architecture/ARCHITECTURE_BOUNDARIES.md[54-74]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


2. Removed DI container documented 🐞 Bug ⚙ Maintainability ⭐ New
Description
The infrastructure instructions tell contributors to register services through dill's
CatalogBuilder, but dill and build_catalog were removed in favor of explicit bootstrap wiring.
Following this example or the new-service recipe therefore references APIs that no longer exist.
Code

docs/architecture/CLEAN_ARCHITECTURE.md[R285-291]

+pub async fn build_catalog(config: AppConfig) -> Result<Catalog> {
+    CatalogBuilder::new()
+        .add_value(config)
+        .add_value(embedding_provider)
+        .add_value(embedding_handle)
+        .add_value(embedding_admin)
+        .build()
Relevance

⭐⭐⭐ High

The documented DI API was explicitly removed and replaced by manual composition.

ⓘ Recommendations generated based on similar findings in past PRs

Evidence
Implemented ADR-050 explicitly removes dill and replaces build_catalog() with manual composition,
and the current initializer builds services through build_bootstrap rather than a catalog.

docs/adr/050-manual-composition-root-dill-removal.md[20-42]
crates/mcb/src/initializers/mcp_server.rs[271-305]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
Replace the obsolete dill/CatalogBuilder examples with the current Loco and manual bootstrap composition flow.

## Issue Context
ADR-050 superseded dill and records that `build_catalog()` was never used and was removed. Current composition occurs through the MCP initializer's bootstrap functions.

## Fix Focus Areas
- docs/architecture/CLEAN_ARCHITECTURE.md[273-332]
- docs/architecture/CLEAN_ARCHITECTURE.md[503-516]
- docs/adr/050-manual-composition-root-dill-removal.md[20-42]
- crates/mcb/src/initializers/mcp_server.rs[271-305]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


3. Invalid provider registration recipe 🐞 Bug ≡ Correctness ⭐ New
Description
The extension recipe registers a zero-argument closure that calls OllamaEmbeddingProvider::new()
without configuration, but registry factories accept &EmbeddingProviderConfig and the Ollama
constructor requires URL, model, timeout, and client arguments. Copying this template will not
type-check and cannot consume runtime provider configuration.
Code

docs/architecture/CLEAN_ARCHITECTURE.md[R370-372]

+    factory: || {
+        Ok(Arc::new(OllamaEmbeddingProvider::new()?))
+    },
Relevance

⭐⭐⭐ High

The example has a deterministic factory-signature mismatch and cannot compile.

ⓘ Recommendations generated based on similar findings in past PRs

Evidence
The registry is parameterized by EmbeddingProviderConfig, and the production Ollama registration
uses fn ollama_factory(config: &EmbeddingProviderConfig) plus the domain registration macro rather
than a zero-argument closure.

crates/mcb-domain/src/registry/embedding.rs[13-56]
crates/mcb-providers/src/embedding/ollama.rs[173-200]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
Rewrite the provider registration examples to use the current configuration-aware factory signature and registration macro.

## Issue Context
Embedding factories receive `&EmbeddingProviderConfig`. The existing Ollama implementation resolves its configuration in a named factory function and registers that function through `register_embedding_provider!`.

## Fix Focus Areas
- docs/architecture/CLEAN_ARCHITECTURE.md[365-373]
- docs/architecture/CLEAN_ARCHITECTURE.md[464-472]
- crates/mcb-domain/src/registry/embedding.rs[13-56]
- crates/mcb-providers/src/embedding/ollama.rs[173-200]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


View more (1)
4. Obsolete schema framework prescribed 🐞 Bug ⚙ Maintainability ⭐ New
Description
The recommended pattern directs contributors to use Schema, TableDef, ColumnDef, and
SchemaDdlGenerator, but the current domain crate exposes no schema module or these declarations.
Adopting the example would require resurrecting a removed framework instead of extending the current
SeaORM entities and migrations.
Code

docs/architecture/CLEAN_ARCHITECTURE.md[R123-125]

+2. Express persistence metadata through domain schema types (`Schema`, `TableDef`, `ColumnDef`).
+3. Keep serialization/transport and DB-specific concerns in outer layers (providers/server).
+4. Generate backend-specific DDL via `SchemaDdlGenerator` implementations in adapters.
Relevance

⭐⭐ Medium

The schema design may be aspirational and aligns with this PR’s stated intent.

ⓘ Recommendations generated based on similar findings in past PRs

Evidence
The domain crate's complete module export list has no schema module, while the implemented project
persistence schema is represented by a SeaORM entity and migration in mcb-providers.

crates/mcb-domain/src/lib.rs[60-81]
crates/mcb-providers/src/database/seaorm/entities/projects.rs[1-32]
crates/mcb-providers/src/database/seaorm/migration/m20260301_000001_initial_schema.rs[11-27]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
Remove or clearly mark the proposed domain-schema framework as a future design, and document the schema mechanism currently implemented in the repository.

## Issue Context
`mcb-domain` exports no schema module. Current persistence shape is represented by provider-layer SeaORM entities and migrations, while validation still recognizes the old root schema symbols as forbidden legacy paths.

## Fix Focus Areas
- docs/architecture/CLEAN_ARCHITECTURE.md[112-127]
- docs/architecture/CLEAN_ARCHITECTURE.md[176-201]
- crates/mcb-domain/src/lib.rs[60-81]
- crates/mcb-providers/src/database/seaorm/entities/projects.rs[1-32]
- crates/mcb-providers/src/database/seaorm/migration/m20260301_000001_initial_schema.rs[11-27]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools



Remediation recommended

5. Nonexistent provider path 🐞 Bug ⚙ Maintainability
Description
The doc’s “after” example points readers to
mcb-providers/src/persistence/sqlite/project_repository.rs, but the SQLite ProjectRepository
implementation in this repo is under
crates/mcb-providers/src/database/sqlite/project_repository.rs. This makes the example hard to
follow and encourages editing/creating the wrong module path.
Code

docs/architecture/CLEAN_ARCHITECTURE.md[R218-219]

+// mcb-providers/src/persistence/sqlite/project_repository.rs
+// Adapter maps Project <-> SQL rows and uses SchemaDdlGenerator for backend DDL.
Evidence
The docs explicitly reference the persistence/sqlite path, while the actual SQLite project
repository lives under crates/mcb-providers/src/database/sqlite/project_repository.rs.

docs/architecture/CLEAN_ARCHITECTURE.md[217-220]
crates/mcb-providers/src/database/sqlite/project_repository.rs[1-20]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
The docs reference a provider file path that doesn’t exist in this repository, which misleads readers.

## Issue Context
The “after” example currently points to `mcb-providers/src/persistence/sqlite/project_repository.rs`, but the actual SQLite implementation is located under `crates/mcb-providers/src/database/sqlite/project_repository.rs`.

## Fix Focus Areas
- docs/architecture/CLEAN_ARCHITECTURE.md[218-220]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


6. Pseudo-code uses real paths 🐞 Bug ⚙ Maintainability
Description
The “Before” snippet uses real repo paths (mcb-domain/src/entities/project.rs,
mcb-providers/src/database/sqlite/project_repository.rs,
mcb-domain/src/ports/repositories/project.rs) while claiming shapes/traits that don’t match the
current code, making it look like an inaccurate description of the actual codebase. This should be
clearly labeled as illustrative (or updated to match real files) to avoid confusing contributors
about the current architecture.
Code

docs/architecture/CLEAN_ARCHITECTURE.md[R136-154]

+// mcb-domain/src/entities/project.rs  (incomplete — missing org_id, path, updated_at)
+pub struct Project {
+    pub id: String,
+    pub name: String,
+}
+
+// mcb-providers/src/database/sqlite/project_repository.rs  (leaks storage type)
+pub struct ProjectRow {
+    pub id: String,
+    pub name: String,
+    pub created_at: i64,
+}
+
+// mcb-domain/src/ports/repositories/project.rs  (trait uses storage type, no tenant scoping)
+#[async_trait]
+pub trait ProjectRepo {
+    async fn save(&self, row: ProjectRow) -> anyhow::Result<()>;
+    async fn get(&self, id: &str) -> anyhow::Result<Option<ProjectRow>>;
+}
Evidence
The documentation’s “before” section claims the domain Project is missing fields and the provider
leaks a ProjectRow, but the current domain entity already includes those fields and the SQLite
provider imports/uses Project directly. The current domain port trait also includes get_by_path,
which the example omits while still using the real file path.

docs/architecture/CLEAN_ARCHITECTURE.md[133-155]
crates/mcb-domain/src/entities/project.rs[14-32]
crates/mcb-providers/src/database/sqlite/project_repository.rs[15-45]
crates/mcb-domain/src/ports/repositories/project.rs[7-27]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
The “Before” example appears to describe real code (it uses real repo file paths), but the structs/traits shown don’t match what is currently implemented. This reads like a factual statement about the repository and can mislead contributors.

## Issue Context
- `Project` in the domain already contains `org_id`, `path`, and `updated_at`.
- The SQLite provider repository uses `Project` directly (no `ProjectRow`).
- The real `ProjectRepository` trait includes `get_by_path`, which the example omits.

## Fix Focus Areas
- docs/architecture/CLEAN_ARCHITECTURE.md[133-155]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools



Informational

7. Domain serialization guidance conflict 🐞 Bug ⚙ Maintainability
Description
The new guidance says to keep serialization/transport concerns in outer layers, but the domain
Project entity currently depends on serde/schemars via derives. The doc should either document
this as an intentional exception/allowed pattern or refine the guidance so it matches current
practice.
Code

docs/architecture/CLEAN_ARCHITECTURE.md[R122-125]

+1. Keep the **canonical model** in `mcb-domain` as the single source of truth.
+2. Express persistence metadata through domain schema types (`Schema`, `TableDef`, `ColumnDef`).
+3. Keep serialization/transport and DB-specific concerns in outer layers (providers/server).
+4. Generate backend-specific DDL via `SchemaDdlGenerator` implementations in adapters.
Evidence
The document explicitly recommends keeping serialization/transport concerns in outer layers, while
the domain Project entity imports/derives serialization/schema traits.

docs/architecture/CLEAN_ARCHITECTURE.md[120-125]
crates/mcb-domain/src/entities/project.rs[14-32]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
The docs recommend keeping serialization/transport concerns out of the domain, but current domain entities derive serde/schemars, making the guidance inconsistent with the codebase.

## Issue Context
`Project` in `mcb-domain` imports `serde` and `schemars` and derives `Serialize`/`Deserialize`.

## Fix Focus Areas
- docs/architecture/CLEAN_ARCHITECTURE.md[120-127]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


Grey Divider

To customize comments, go to the Qodo configuration screen, or learn more in the docs.

Previous review results

Review updated until commit 772a5d6 ⚖️ Balanced

Results up to commit f828ea9 ⚖️ Balanced


No changes from previous review

Qodo Logo

Comment on lines +218 to +219
// mcb-providers/src/persistence/sqlite/project_repository.rs
// Adapter maps Project <-> SQL rows and uses SchemaDdlGenerator for backend DDL.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remediation recommended

1. Nonexistent provider path 🐞 Bug ⚙ Maintainability

The doc’s “after” example points readers to
mcb-providers/src/persistence/sqlite/project_repository.rs, but the SQLite ProjectRepository
implementation in this repo is under
crates/mcb-providers/src/database/sqlite/project_repository.rs. This makes the example hard to
follow and encourages editing/creating the wrong module path.
Agent Prompt
## Issue description
The docs reference a provider file path that doesn’t exist in this repository, which misleads readers.

## Issue Context
The “after” example currently points to `mcb-providers/src/persistence/sqlite/project_repository.rs`, but the actual SQLite implementation is located under `crates/mcb-providers/src/database/sqlite/project_repository.rs`.

## Fix Focus Areas
- docs/architecture/CLEAN_ARCHITECTURE.md[218-220]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools

Comment on lines +136 to +154
// mcb-domain/src/entities/project.rs (incomplete — missing org_id, path, updated_at)
pub struct Project {
pub id: String,
pub name: String,
}

// mcb-providers/src/database/sqlite/project_repository.rs (leaks storage type)
pub struct ProjectRow {
pub id: String,
pub name: String,
pub created_at: i64,
}

// mcb-domain/src/ports/repositories/project.rs (trait uses storage type, no tenant scoping)
#[async_trait]
pub trait ProjectRepo {
async fn save(&self, row: ProjectRow) -> anyhow::Result<()>;
async fn get(&self, id: &str) -> anyhow::Result<Option<ProjectRow>>;
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remediation recommended

2. Pseudo-code uses real paths 🐞 Bug ⚙ Maintainability

The “Before” snippet uses real repo paths (mcb-domain/src/entities/project.rs,
mcb-providers/src/database/sqlite/project_repository.rs,
mcb-domain/src/ports/repositories/project.rs) while claiming shapes/traits that don’t match the
current code, making it look like an inaccurate description of the actual codebase. This should be
clearly labeled as illustrative (or updated to match real files) to avoid confusing contributors
about the current architecture.
Agent Prompt
## Issue description
The “Before” example appears to describe real code (it uses real repo file paths), but the structs/traits shown don’t match what is currently implemented. This reads like a factual statement about the repository and can mislead contributors.

## Issue Context
- `Project` in the domain already contains `org_id`, `path`, and `updated_at`.
- The SQLite provider repository uses `Project` directly (no `ProjectRow`).
- The real `ProjectRepository` trait includes `get_by_path`, which the example omits.

## Fix Focus Areas
- docs/architecture/CLEAN_ARCHITECTURE.md[133-155]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools

Comment on lines +122 to +125
1. Keep the **canonical model** in `mcb-domain` as the single source of truth.
2. Express persistence metadata through domain schema types (`Schema`, `TableDef`, `ColumnDef`).
3. Keep serialization/transport and DB-specific concerns in outer layers (providers/server).
4. Generate backend-specific DDL via `SchemaDdlGenerator` implementations in adapters.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Informational

3. Domain serialization guidance conflict 🐞 Bug ⚙ Maintainability

The new guidance says to keep serialization/transport concerns in outer layers, but the domain
Project entity currently depends on serde/schemars via derives. The doc should either document
this as an intentional exception/allowed pattern or refine the guidance so it matches current
practice.
Agent Prompt
## Issue description
The docs recommend keeping serialization/transport concerns out of the domain, but current domain entities derive serde/schemars, making the guidance inconsistent with the codebase.

## Issue Context
`Project` in `mcb-domain` imports `serde` and `schemars` and derives `Serialize`/`Deserialize`.

## Fix Focus Areas
- docs/architecture/CLEAN_ARCHITECTURE.md[120-127]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools

@qodo-code-review

Copy link
Copy Markdown
Contributor

Code review by qodo was updated up to the latest commit f828ea9

Comment on lines +24 to +26
│ Layer 4: Application Services & Use Cases │
│ (orchestration, business logic, registry) │
│ Crate: mcb-application │

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Action required

1. Nonexistent application layer 🐞 Bug ⚙ Maintainability

The layer model assigns services and registries to an mcb-application crate that is not a
workspace member, so contributors cannot place or import code as documented. The actual seven-crate
workspace includes mcb-utils and mcb-validate, which this model omits.
Agent Prompt
## Issue description
The architecture model introduces a nonexistent `mcb-application` crate while omitting actual workspace crates. Update the document to use the repository's real crate ownership and dependency structure.

## Issue Context
The workspace and boundary documentation define seven crates: `mcb`, `mcb-utils`, `mcb-domain`, `mcb-providers`, `mcb-infrastructure`, `mcb-server`, and `mcb-validate`.

## Fix Focus Areas
- docs/architecture/CLEAN_ARCHITECTURE.md[6-46]
- docs/architecture/CLEAN_ARCHITECTURE.md[229-267]
- Cargo.toml[1-11]
- docs/architecture/ARCHITECTURE_BOUNDARIES.md[54-74]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools

Comment on lines +285 to +291
pub async fn build_catalog(config: AppConfig) -> Result<Catalog> {
CatalogBuilder::new()
.add_value(config)
.add_value(embedding_provider)
.add_value(embedding_handle)
.add_value(embedding_admin)
.build()

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Action required

2. Removed di container documented 🐞 Bug ⚙ Maintainability

The infrastructure instructions tell contributors to register services through dill's
CatalogBuilder, but dill and build_catalog were removed in favor of explicit bootstrap wiring.
Following this example or the new-service recipe therefore references APIs that no longer exist.
Agent Prompt
## Issue description
Replace the obsolete dill/CatalogBuilder examples with the current Loco and manual bootstrap composition flow.

## Issue Context
ADR-050 superseded dill and records that `build_catalog()` was never used and was removed. Current composition occurs through the MCP initializer's bootstrap functions.

## Fix Focus Areas
- docs/architecture/CLEAN_ARCHITECTURE.md[273-332]
- docs/architecture/CLEAN_ARCHITECTURE.md[503-516]
- docs/adr/050-manual-composition-root-dill-removal.md[20-42]
- crates/mcb/src/initializers/mcp_server.rs[271-305]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools

Comment on lines +123 to +125
2. Express persistence metadata through domain schema types (`Schema`, `TableDef`, `ColumnDef`).
3. Keep serialization/transport and DB-specific concerns in outer layers (providers/server).
4. Generate backend-specific DDL via `SchemaDdlGenerator` implementations in adapters.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Action required

3. Obsolete schema framework prescribed 🐞 Bug ⚙ Maintainability

The recommended pattern directs contributors to use Schema, TableDef, ColumnDef, and
SchemaDdlGenerator, but the current domain crate exposes no schema module or these declarations.
Adopting the example would require resurrecting a removed framework instead of extending the current
SeaORM entities and migrations.
Agent Prompt
## Issue description
Remove or clearly mark the proposed domain-schema framework as a future design, and document the schema mechanism currently implemented in the repository.

## Issue Context
`mcb-domain` exports no schema module. Current persistence shape is represented by provider-layer SeaORM entities and migrations, while validation still recognizes the old root schema symbols as forbidden legacy paths.

## Fix Focus Areas
- docs/architecture/CLEAN_ARCHITECTURE.md[112-127]
- docs/architecture/CLEAN_ARCHITECTURE.md[176-201]
- crates/mcb-domain/src/lib.rs[60-81]
- crates/mcb-providers/src/database/seaorm/entities/projects.rs[1-32]
- crates/mcb-providers/src/database/seaorm/migration/m20260301_000001_initial_schema.rs[11-27]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools

Comment on lines +370 to +372
factory: || {
Ok(Arc::new(OllamaEmbeddingProvider::new()?))
},

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Action required

4. Invalid provider registration recipe 🐞 Bug ≡ Correctness

The extension recipe registers a zero-argument closure that calls OllamaEmbeddingProvider::new()
without configuration, but registry factories accept &EmbeddingProviderConfig and the Ollama
constructor requires URL, model, timeout, and client arguments. Copying this template will not
type-check and cannot consume runtime provider configuration.
Agent Prompt
## Issue description
Rewrite the provider registration examples to use the current configuration-aware factory signature and registration macro.

## Issue Context
Embedding factories receive `&EmbeddingProviderConfig`. The existing Ollama implementation resolves its configuration in a named factory function and registers that function through `register_embedding_provider!`.

## Fix Focus Areas
- docs/architecture/CLEAN_ARCHITECTURE.md[365-373]
- docs/architecture/CLEAN_ARCHITECTURE.md[464-472]
- crates/mcb-domain/src/registry/embedding.rs[13-56]
- crates/mcb-providers/src/embedding/ollama.rs[173-200]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools

@qodo-code-review

Copy link
Copy Markdown
Contributor

Code review by qodo was updated up to the latest commit 772a5d6

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

12 issues found across 1 file

Confidence score: 3/5

  • docs/architecture/CLEAN_ARCHITECTURE.md currently describes a canonical schema, application layer (mcb-application), and DI flow (CatalogBuilder/build_catalog()) that do not exist, so contributors following it can be led into dead-end implementations and duplicate architecture patterns—realign these sections to the current AppContext composition root and existing workspace crates.
  • docs/architecture/CLEAN_ARCHITECTURE.md has a reversed dependency graph and incorrect domain boundary claims, which can cause reviewers and contributors to enforce the wrong layering decisions in future changes—update diagrams/rules to match Cargo manifests and ADR-050 as the authoritative boundaries.
  • docs/architecture/CLEAN_ARCHITECTURE.md references nonexistent public API symbols (for example mcb_infrastructure::AppContext) and mismatched port/trait contracts (VectorStoreProvider, EmbeddingProvider), so copy-pasted examples will not compile and extension work may stall—replace snippets with current McbApp/McpServer exports and exact trait method sets.
  • docs/architecture/CLEAN_ARCHITECTURE.md appears to replace a stable-link page with a second, already-stale full architecture spec, creating two competing sources of truth that will drift further—keep normative architecture detail in ADRs and convert this page to a pointer/synopsis to reduce future regression risk.
Prompt for AI agents (unresolved issues)

Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.


<file name="docs/architecture/CLEAN_ARCHITECTURE.md">

<violation number="1" location="docs/architecture/CLEAN_ARCHITECTURE.md:6">
P2: Replacing the stable-link page with a second full architecture specification creates a competing source of truth, and the copy is already stale relative to Cargo manifests and ADR-050. Keeping the normative detail in `ARCHITECTURE.md`/`PATTERNS.md` and limiting this file to focused unified-schema material plus links would avoid maintaining two divergent architecture descriptions.</violation>

<violation number="2" location="docs/architecture/CLEAN_ARCHITECTURE.md:26">
P1: The documented application layer cannot be followed because `mcb-application` is not a workspace crate. This also makes the service, registry, dependency, and extension guidance that follows point contributors at a nonexistent location. The layer should be mapped to the actual seven-crate workspace and its real service/registry locations.</violation>

<violation number="3" location="docs/architecture/CLEAN_ARCHITECTURE.md:66">
P2: This public-API example references a nonexistent `mcb_infrastructure::AppContext`, so users copying it or looking for that facade export will fail. Replace it with the actual `McbApp`/`McpServer` exports or clearly label a proposed API.</violation>

<violation number="4" location="docs/architecture/CLEAN_ARCHITECTURE.md:71">
P3: The layer numbering is internally inconsistent: the overview calls domain Layer 3, while this heading calls it Layer 2 (and providers are Layer 2 in the overview but Layer 5 later). Aligning all headings with the overview—or removing ordinal numbers—would make layer references unambiguous.</violation>

<violation number="5" location="docs/architecture/CLEAN_ARCHITECTURE.md:96">
P2: The documented `VectorStoreProvider` contract does not match the actual port, so the `ContextService` example calling `search` cannot compile. Use the real collection-aware methods or mark the snippet as pseudocode.</violation>

<violation number="6" location="docs/architecture/CLEAN_ARCHITECTURE.md:110">
P2: The stated domain dependency boundary is false and may cause contributors to reject dependencies that are already part of the enforced architecture. Reference the manifest or accurately list the allowed dependency categories.</violation>

<violation number="7" location="docs/architecture/CLEAN_ARCHITECTURE.md:123">
P1: The “canonical schema” recommendation describes an API and persistence architecture that do not exist in this repository. A contributor following it cannot compile the example and would create a second schema source alongside the implemented SeaORM entities/migrations. This section should document the current entity-first SeaORM flow, or be explicitly marked as a proposal and introduced together with the referenced schema APIs.</violation>

<violation number="8" location="docs/architecture/CLEAN_ARCHITECTURE.md:275">
P2: The DI guidance has reverted to the removed dill/Catalog architecture. ADR-050 records that `CatalogBuilder` and `build_catalog()` were deleted in favor of the manual `AppContext` composition root, so this example sends contributors toward unavailable APIs. The infrastructure responsibilities and examples should describe the current manual wiring plus linkme discovery.</violation>

<violation number="9" location="docs/architecture/CLEAN_ARCHITECTURE.md:432">
P2: The dependency graph reverses the facade edge: the actual `mcb` facade depends on the internal crates; `mcb-domain` does not depend on `mcb`. Because this diagram is paired with the “Dependencies flow INWARD” rule, it currently teaches a dependency that would violate the enforced domain boundary. The arrows should match the Cargo manifests and treat the facade as an outer composition/entry crate.</violation>

<violation number="10" location="docs/architecture/CLEAN_ARCHITECTURE.md:457">
P2: The “Adding a New Embedding Provider” implementation does not satisfy the current `EmbeddingProvider` trait. Include the three required methods so the extension pattern is copyable.</violation>

<violation number="11" location="docs/architecture/CLEAN_ARCHITECTURE.md:479">
P2: This extension example does not compile because `switch_to_my_provider` returns `()` while using `?`. Returning `Result<()>` and completing with `Ok(())` makes the documented usage valid.</violation>

<violation number="12" location="docs/architecture/CLEAN_ARCHITECTURE.md:527">
P2: The new-service handler example returns `Result<()>` from `do_something()` where its signature promises `Result<MyToolResponse>`, so it cannot compile. The example should await the service call, construct the documented response, and return `Ok(response)` (or align the handler signature with the service result if no response payload is intended).</violation>
</file>

Shadow auto-approve: would not auto-approve because issues were found.
Tip: instead of fixing issues one by one fix them all with cubic

Re-trigger cubic

Recommended pattern:

1. Keep the **canonical model** in `mcb-domain` as the single source of truth.
2. Express persistence metadata through domain schema types (`Schema`, `TableDef`, `ColumnDef`).

@cubic-dev-ai cubic-dev-ai Bot Jul 29, 2026

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1: The “canonical schema” recommendation describes an API and persistence architecture that do not exist in this repository. A contributor following it cannot compile the example and would create a second schema source alongside the implemented SeaORM entities/migrations. This section should document the current entity-first SeaORM flow, or be explicitly marked as a proposal and introduced together with the referenced schema APIs.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At docs/architecture/CLEAN_ARCHITECTURE.md, line 123:

<comment>The “canonical schema” recommendation describes an API and persistence architecture that do not exist in this repository. A contributor following it cannot compile the example and would create a second schema source alongside the implemented SeaORM entities/migrations. This section should document the current entity-first SeaORM flow, or be explicitly marked as a proposal and introduced together with the referenced schema APIs.</comment>

<file context>
@@ -1,18 +1,621 @@
+Recommended pattern:
+
+1. Keep the **canonical model** in `mcb-domain` as the single source of truth.
+2. Express persistence metadata through domain schema types (`Schema`, `TableDef`, `ColumnDef`).
+3. Keep serialization/transport and DB-specific concerns in outer layers (providers/server).
+4. Generate backend-specific DDL via `SchemaDdlGenerator` implementations in adapters.
</file context>
Fix with cubic

┌─────────────────────────────────────────────────────────────┐
│ Layer 4: Application Services & Use Cases │
│ (orchestration, business logic, registry) │
│ Crate: mcb-application │

@cubic-dev-ai cubic-dev-ai Bot Jul 29, 2026

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1: The documented application layer cannot be followed because mcb-application is not a workspace crate. This also makes the service, registry, dependency, and extension guidance that follows point contributors at a nonexistent location. The layer should be mapped to the actual seven-crate workspace and its real service/registry locations.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At docs/architecture/CLEAN_ARCHITECTURE.md, line 26:

<comment>The documented application layer cannot be followed because `mcb-application` is not a workspace crate. This also makes the service, registry, dependency, and extension guidance that follows point contributors at a nonexistent location. The layer should be mapped to the actual seven-crate workspace and its real service/registry locations.</comment>

<file context>
@@ -1,18 +1,621 @@
+┌─────────────────────────────────────────────────────────────┐
+│ Layer 4: Application Services & Use Cases                   │
+│ (orchestration, business logic, registry)                   │
+│ Crate: mcb-application                                      │
+└─────────────────────────────────────────────────────────────┘
+                            ↓
</file context>
Fix with cubic

}

pub trait VectorStoreProvider: Send + Sync {
async fn store(&self, embedding: Embedding) -> Result<()>;

@cubic-dev-ai cubic-dev-ai Bot Jul 29, 2026

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2: The documented VectorStoreProvider contract does not match the actual port, so the ContextService example calling search cannot compile. Use the real collection-aware methods or mark the snippet as pseudocode.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At docs/architecture/CLEAN_ARCHITECTURE.md, line 96:

<comment>The documented `VectorStoreProvider` contract does not match the actual port, so the `ContextService` example calling `search` cannot compile. Use the real collection-aware methods or mark the snippet as pseudocode.</comment>

<file context>
@@ -1,18 +1,621 @@
+}
+
+pub trait VectorStoreProvider: Send + Sync {
+    async fn store(&self, embedding: Embedding) -> Result<()>;
+    async fn search(&self, query: &Embedding) -> Result<Vec<SearchResult>>;
+}
</file context>
Fix with cubic

}

#[async_trait]
impl EmbeddingProvider for MyEmbeddingProvider {

@cubic-dev-ai cubic-dev-ai Bot Jul 29, 2026

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2: The “Adding a New Embedding Provider” implementation does not satisfy the current EmbeddingProvider trait. Include the three required methods so the extension pattern is copyable.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At docs/architecture/CLEAN_ARCHITECTURE.md, line 457:

<comment>The “Adding a New Embedding Provider” implementation does not satisfy the current `EmbeddingProvider` trait. Include the three required methods so the extension pattern is copyable.</comment>

<file context>
@@ -1,18 +1,621 @@
+}
+
+#[async_trait]
+impl EmbeddingProvider for MyEmbeddingProvider {
+    async fn embed(&self, text: &str) -> Result<Embedding> {
+        // Implementation
</file context>
Fix with cubic

}
```

**Dependency**: None (except standard library + thiserror)

@cubic-dev-ai cubic-dev-ai Bot Jul 29, 2026

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2: The stated domain dependency boundary is false and may cause contributors to reject dependencies that are already part of the enforced architecture. Reference the manifest or accurately list the allowed dependency categories.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At docs/architecture/CLEAN_ARCHITECTURE.md, line 110:

<comment>The stated domain dependency boundary is false and may cause contributors to reject dependencies that are already part of the enforced architecture. Reference the manifest or accurately list the allowed dependency categories.</comment>

<file context>
@@ -1,18 +1,621 @@
+}
+```
+
+**Dependency**: None (except standard library + thiserror)
+
+#### Unified Domain Data Model (Entities + Schemas + Traits)
</file context>
Fix with cubic

Comment on lines +479 to +481
pub async fn switch_to_my_provider(admin: &dyn EmbeddingAdminInterface) {
admin.switch_provider("my_provider").await?;
}

@cubic-dev-ai cubic-dev-ai Bot Jul 29, 2026

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2: This extension example does not compile because switch_to_my_provider returns () while using ?. Returning Result<()> and completing with Ok(()) makes the documented usage valid.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At docs/architecture/CLEAN_ARCHITECTURE.md, line 479:

<comment>This extension example does not compile because `switch_to_my_provider` returns `()` while using `?`. Returning `Result<()>` and completing with `Ok(())` makes the documented usage valid.</comment>

<file context>
@@ -1,18 +1,621 @@
+
+```rust
+// Automatically discovered and available for switching
+pub async fn switch_to_my_provider(admin: &dyn EmbeddingAdminInterface) {
+    admin.switch_provider("my_provider").await?;
+}
</file context>
Suggested change
pub async fn switch_to_my_provider(admin: &dyn EmbeddingAdminInterface) {
admin.switch_provider("my_provider").await?;
}
pub async fn switch_to_my_provider(admin: &dyn EmbeddingAdminInterface) -> Result<()> {
admin.switch_provider("my_provider").await?;
Ok(())
}
Fix with cubic

@@ -1,18 +1,621 @@
<!-- markdownlint-disable MD013 MD024 MD025 MD003 MD022 MD031 MD032 MD036 MD041 MD060 -->

@cubic-dev-ai cubic-dev-ai Bot Jul 29, 2026

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2: Replacing the stable-link page with a second full architecture specification creates a competing source of truth, and the copy is already stale relative to Cargo manifests and ADR-050. Keeping the normative detail in ARCHITECTURE.md/PATTERNS.md and limiting this file to focused unified-schema material plus links would avoid maintaining two divergent architecture descriptions.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At docs/architecture/CLEAN_ARCHITECTURE.md, line 6:

<comment>Replacing the stable-link page with a second full architecture specification creates a competing source of truth, and the copy is already stale relative to Cargo manifests and ADR-050. Keeping the normative detail in `ARCHITECTURE.md`/`PATTERNS.md` and limiting this file to focused unified-schema material plus links would avoid maintaining two divergent architecture descriptions.</comment>

<file context>
@@ -1,18 +1,621 @@
+
+## Overview
+
+Memory Context Browser follows **Clean Architecture** principles with strict layer separation across 7 Cargo workspace crates. This document explains the architecture, layer interactions, and extension patterns.
+
+## The 6 Layers
</file context>
Fix with cubic

mcb-domain
mcb (facade)

@cubic-dev-ai cubic-dev-ai Bot Jul 29, 2026

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2: The dependency graph reverses the facade edge: the actual mcb facade depends on the internal crates; mcb-domain does not depend on mcb. Because this diagram is paired with the “Dependencies flow INWARD” rule, it currently teaches a dependency that would violate the enforced domain boundary. The arrows should match the Cargo manifests and treat the facade as an outer composition/entry crate.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At docs/architecture/CLEAN_ARCHITECTURE.md, line 432:

<comment>The dependency graph reverses the facade edge: the actual `mcb` facade depends on the internal crates; `mcb-domain` does not depend on `mcb`. Because this diagram is paired with the “Dependencies flow INWARD” rule, it currently teaches a dependency that would violate the enforced domain boundary. The arrows should match the Cargo manifests and treat the facade as an outer composition/entry crate.</comment>

<file context>
@@ -1,18 +1,621 @@
+    ↓
+mcb-domain
+    ↓
+mcb (facade)
+```
+
</file context>
Fix with cubic


#### Responsibilities

- Build DI container (dill Catalog)

@cubic-dev-ai cubic-dev-ai Bot Jul 29, 2026

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2: The DI guidance has reverted to the removed dill/Catalog architecture. ADR-050 records that CatalogBuilder and build_catalog() were deleted in favor of the manual AppContext composition root, so this example sends contributors toward unavailable APIs. The infrastructure responsibilities and examples should describe the current manual wiring plus linkme discovery.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At docs/architecture/CLEAN_ARCHITECTURE.md, line 275:

<comment>The DI guidance has reverted to the removed dill/Catalog architecture. ADR-050 records that `CatalogBuilder` and `build_catalog()` were deleted in favor of the manual `AppContext` composition root, so this example sends contributors toward unavailable APIs. The infrastructure responsibilities and examples should describe the current manual wiring plus linkme discovery.</comment>

<file context>
@@ -1,18 +1,621 @@
+
+#### Responsibilities
+
+- Build DI container (dill Catalog)
+- Load configuration (Figment)
+- Provide provider handles (RwLock wrappers for runtime switching)
</file context>
Fix with cubic


**Dependency**: Imports from all other crates (but only re-exports public types)

### Layer 2: Domain (mcb-domain)

@cubic-dev-ai cubic-dev-ai Bot Jul 29, 2026

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P3: The layer numbering is internally inconsistent: the overview calls domain Layer 3, while this heading calls it Layer 2 (and providers are Layer 2 in the overview but Layer 5 later). Aligning all headings with the overview—or removing ordinal numbers—would make layer references unambiguous.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At docs/architecture/CLEAN_ARCHITECTURE.md, line 71:

<comment>The layer numbering is internally inconsistent: the overview calls domain Layer 3, while this heading calls it Layer 2 (and providers are Layer 2 in the overview but Layer 5 later). Aligning all headings with the overview—or removing ordinal numbers—would make layer references unambiguous.</comment>

<file context>
@@ -1,18 +1,621 @@
+
+**Dependency**: Imports from all other crates (but only re-exports public types)
+
+### Layer 2: Domain (mcb-domain)
+
+**Purpose**: Business rules and domain entities
</file context>
Fix with cubic

@marlon-costa-dc

Copy link
Copy Markdown
Collaborator Author

Fechando como superseded pela SSOT atual na main.

Evidence: docs/architecture/CLEAN_ARCHITECTURE.md na main é deliberadamente um stub de link estável que aponta para ARCHITECTURE.md (231 seções, cobre layers, crates, dependency rules, port categories) e PATTERNS.md como SSOT. Este PR reverte o stub para um documento completo de 621 linhas duplicando ARCHITECTURE.md/PATTERNS.md — reintroduziria old+new coexistence que a main já eliminou (violação de SSOT).

Nenhum conteúdo único identificado no diff que já não esteja coberto pela SSOT atual. Se houver seção específica que deva migrar para ARCHITECTURE.md, reabrir com escopo reduzido.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants