Skip to content

Commit e284abd

Browse files
committed
feat: Update architecture and product documentation for webapp mode
- Added new ADRs for logging, database migrations, web fetch timeouts, tray feature defaults, and packaging strategy. - Updated PRD to reflect changes in the application model, emphasizing webapp functionality. - Revised dashboard generation timestamp and next actions. - Modified status.yaml to point to the new product brief and updated recommendations. - Enhanced tray functionality and UI interactions in the codebase. - Created new product brief for webapp mode detailing user needs and expected outcomes. - Initiated architecture planning story to address open design questions and prioritize implementation tasks.
1 parent c6fe57e commit e284abd

17 files changed

Lines changed: 598 additions & 117 deletions
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
# ADR-05 — Logging & Observability
2+
3+
Status: proposed
4+
5+
Context
6+
---------
7+
The codebase currently emits errors via `eprintln!` with no structured logging. As implementation moves into the Implementation phase we need predictable, configurable logs for debugging, local troubleshooting, and optional file-based capture for releases.
8+
9+
Decision
10+
---------
11+
Adopt the `log` facade crate for logging calls and initialize a small runtime logger by default:
12+
13+
- Use `log` for logging macros (`error!`, `warn!`, `info!`, `debug!`, `trace!`).
14+
- Use `env_logger` as the default logger (respect `RUST_LOG` for verbosity control).
15+
- Provide an optional feature `file_logging` that enables `flexi_logger` (or similar) for file rotation in packaged releases.
16+
17+
Consequences
18+
------------
19+
- Pros: consistent logging API across crates, easy to control output during development with `RUST_LOG`, optional file capture for releases, better diagnostics than `eprintln!`.
20+
- Cons: small dependency addition and a few code changes to replace `eprintln!` calls.
21+
22+
Implementation Notes
23+
--------------------
24+
- Add dependencies: `log = "0.4"`, `env_logger = "0.9"`. Optional: `flexi_logger = { version = "*", optional = true }` behind a `file_logging` feature.
25+
- Initialize the logger early in `main.rs` (e.g. `env_logger::init();`), or use `flexi_logger` setup when `file_logging` feature is active.
26+
- Replace `eprintln!` with `log::error!`/`info!` as appropriate; avoid logging sensitive user data.
27+
28+
Acceptance Criteria
29+
-------------------
30+
- `main.rs` initializes a logger and `RUST_LOG` controls log level during run.
31+
- No calls to `eprintln!` remain for error reporting (transitional exceptions OK with TODOs).
32+
- README documents how to enable file logging and how to use `RUST_LOG`.
33+
34+
Next Steps / Follow-ups
35+
----------------------
36+
- Create a small dev story to add dependencies and init code, then a follow-up PR that replaces `eprintln!` usage across modules.
37+
38+
(end)
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
# ADR-06 — Database File Location & Migrations
2+
3+
Status: proposed
4+
5+
Context
6+
---------
7+
The repository currently contains a runtime SQLite DB file (`rustine.db`). This risks leaking local data and polluting repository history. In addition, we need a deterministic migration strategy for schema changes.
8+
9+
Decision
10+
---------
11+
1. Store the runtime database in an OS-appropriate user data directory instead of the repo root. Use `directories` or `dirs-next` to compute a path such as:
12+
- Windows: `%APPDATA%/Rustine/rustine.db`
13+
- macOS: `~/Library/Application Support/Rustine/rustine.db`
14+
- Linux: `$XDG_DATA_HOME/rustine/rustine.db` (fall back to `~/.local/share`)
15+
2. Add a small, embedded migration system. Keep SQL migration files under `bmad/migrations/` (e.g. `0001_create_tables.sql`) and apply them at startup. Use a lightweight approach (loop over files and execute) or a crate such as `rusqlite_migration`.
16+
3. Provide an environment variable override `RUSTINE_DB_PATH` for testing and CI to allow `:memory:` or custom paths.
17+
18+
Consequences
19+
------------
20+
- Pros: avoids committing runtime data, clearer upgrade path for schema changes, reproducible local installs.
21+
- Cons: small change to startup code and need to manage migrations.
22+
23+
Implementation Notes
24+
--------------------
25+
- Update `db::init_db()` to compute the DB path via `directories::ProjectDirs::from("com", "medyll", "rustine")` and create the directory if missing.
26+
- Implement migration runner: list files in `bmad/migrations/` ordered by name and execute each SQL file atomically; record applied migrations in a `schema_migrations` table.
27+
- Add `rustine.db` to `.gitignore` (separate small patch / dev story).
28+
29+
Acceptance Criteria
30+
-------------------
31+
- Default runtime DB is created under the OS app data directory.
32+
- Migration files live in `bmad/migrations/` and are executed at startup where needed.
33+
- Tests and CI override DB path via `RUSTINE_DB_PATH` where necessary.
34+
35+
Next Steps / Follow-ups
36+
----------------------
37+
- Dev story: implement path resolution and migration runner, add `rustine.db` to `.gitignore`, add seed/example migration files.
38+
39+
(end)
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
# ADR-07 — Web Fetch Timeouts for Metadata
2+
3+
Status: proposed
4+
5+
Context
6+
---------
7+
The app performs blocking HTTP requests in background threads to fetch favicons and site metadata. Currently requests use `reqwest::blocking::get` without explicit timeouts which can cause fetch threads to hang indefinitely on slow or unresponsive hosts (AUDIT-003).
8+
9+
Decision
10+
---------
11+
Create and reuse a `reqwest::blocking::Client` configured with reasonable timeouts and a sensible `User-Agent` header. Use `once_cell::sync::OnceCell` or `lazy_static` to store a shared client instance.
12+
13+
Recommended timeout values (tunable):
14+
- `connect_timeout`: 5 seconds
15+
- `timeout`: 20 seconds (overall request)
16+
17+
Consequences
18+
------------
19+
- Pros: fetch threads will fail-fast on unresponsive hosts and not block indefinitely; easier to reason about background work.
20+
- Cons: some very slow sites may not yield metadata, but core app functionality (opening URLs) remains unaffected.
21+
22+
Implementation Notes
23+
--------------------
24+
- Build the client in `webview` or a small `http` util module:
25+
26+
```rust
27+
let client = reqwest::blocking::Client::builder()
28+
.connect_timeout(Duration::from_secs(5))
29+
.timeout(Duration::from_secs(20))
30+
.user_agent("rustine/0.1 (+https://github.com/medyll/rustine)")
31+
.build()?;
32+
```
33+
34+
- Use this client for all metadata requests and handle timeout errors gracefully.
35+
36+
Acceptance Criteria
37+
-------------------
38+
- Metadata fetches return an error after the configured timeout.
39+
- No background fetch thread remains blocked waiting on network IO beyond the configured timeout.
40+
41+
Next Steps / Follow-ups
42+
----------------------
43+
- Dev story: replace `reqwest::blocking::get` calls with the shared client; add unit/integration tests that simulate slow servers (using a local test server) to validate timeout behavior.
44+
45+
(end)
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
# ADR-08 — Default for `real_tray` Feature
2+
3+
Status: proposed
4+
5+
Context
6+
---------
7+
Tray/menu integration is gated behind the `real_tray` feature. The audit noted the feature is enabled by default which can complicate CI and headless testing environments (AUDIT-007).
8+
9+
Decision
10+
---------
11+
Make `real_tray` an optional feature and disable it in the default feature set. Document how to enable it for developer machines and for packaged releases.
12+
13+
Rationale:
14+
- CI and headless environments should be able to build and run tests without platform-specific tray dependencies or requiring a GUI environment.
15+
- Packaged user-facing builds can enable `real_tray` during packaging or in release manifests.
16+
17+
Consequences
18+
------------
19+
- Pros: simpler CI, fewer platform-specific build failures.
20+
- Cons: local developer experience requires enabling the feature to get tray functionality; documentation must be clear.
21+
22+
Implementation Notes
23+
--------------------
24+
- Update `Cargo.toml` to make `real_tray` optional (remove from default features).
25+
- Update README with `--features real_tray` instructions and document how packaging enables the feature.
26+
27+
Acceptance Criteria
28+
-------------------
29+
- Default builds (CI) compile without `real_tray` and pass tests.
30+
- README documents how to enable tray support locally and in release builds.
31+
32+
Next Steps / Follow-ups
33+
----------------------
34+
- Dev story: update `Cargo.toml` and CI templates; run a full CI build to validate.
35+
36+
(end)
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
# ADR-09 — Packaging & Distribution Strategy
2+
3+
Status: proposed
4+
5+
Context
6+
---------
7+
This is a local desktop app (Windows/macOS/Linux). We need a repeatable packaging strategy to produce user-friendly installers or archives and a reproducible CI pipeline to produce release artifacts.
8+
9+
Decision
10+
---------
11+
Adopt a pragmatic, staged approach:
12+
13+
1. Short-term (first releases): build release binaries for each platform and publish zipped artifacts or platform-idiomatic archives to GitHub Releases (CI produces artifacts).
14+
2. Medium-term: add platform packaging where practical:
15+
- Linux: AppImage (or .deb via `cargo-deb`) for single-file distribution.
16+
- Windows: zip of executable or MSI via WiX / `cargo-wix` for an installer.
17+
- macOS: DMG or zip containing the .app bundle.
18+
3. Ensure assets are included: the Tailwind-built `dist/styles.css` and application icons; add packaging scripts to assemble final bundles.
19+
20+
Consequences
21+
------------
22+
- Pros: quick release path, platform-appropriate packages, reproducible CI artifacts.
23+
- Cons: adds CI complexity and packaging tooling dependencies.
24+
25+
Implementation Notes
26+
--------------------
27+
- Add a GitHub Actions workflow (or extend existing CI) that builds release binaries for each runner and assembles artifacts.
28+
- Add packaging scripts under `scripts/` to create AppImage/MSI/DMG as needed.
29+
- Ensure CSS build (`pnpm run build:css`) runs before packaging and that `assets/` are copied into the bundle.
30+
31+
Acceptance Criteria
32+
-------------------
33+
- CI produces platform release artifacts with CSS and icons included.
34+
- Packaging scripts exist and are documented in the README.
35+
36+
Next Steps / Follow-ups
37+
----------------------
38+
- Dev story: implement CI release workflow, add packaging scripts, test installers on each platform.
39+
40+
(end)

bmad/artifacts/architecture.md

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,16 @@ A native desktop application where all components run in a single process. The d
126126

127127
---
128128

129+
## Additional ADRs (new)
130+
131+
- ADR-05 — Logging & Observability — bmad/artifacts/adrs/ADR-05-logging-observability.md
132+
- ADR-06 — Database file location & migrations — bmad/artifacts/adrs/ADR-06-db-file-location-and-migrations.md
133+
- ADR-07 — Web fetch timeouts for metadata — bmad/artifacts/adrs/ADR-07-webfetch-timeouts.md
134+
- ADR-08 — Default for `real_tray` feature — bmad/artifacts/adrs/ADR-08-tray-feature-default.md
135+
- ADR-09 — Packaging & distribution strategy — bmad/artifacts/adrs/ADR-09-packaging-distribution.md
136+
137+
---
138+
129139
## Data Flow
130140

131141
### Flow: Add New URL

bmad/artifacts/dashboard.md

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# BMAD Dashboard - rustine
22

3-
Generated: 2026-03-06
3+
Generated: 2026-03-07T16:57:21Z — PRD merged; prd-webapp.md removed
44

55
---
66

@@ -32,5 +32,4 @@ Generated: 2026-03-06
3232

3333
## Next Actions
3434

35-
- bmad dev story AUDIT-001
36-
- bmad dev story AUDIT-002
35+
- bmad dev story PLAN-ARCH
Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
version: 1
2+
project:
3+
name: rustine
4+
type: single-package
5+
stack:
6+
- Rust 2021
7+
- Dioxus Desktop
8+
- SQLite (rusqlite bundled)
9+
- Tailwind CSS (pnpm)
10+
- Reqwest (blocking)
11+
phases:
12+
- name: Analysis
13+
status: completed
14+
- name: Planning
15+
status: completed
16+
- name: Solutioning
17+
status: completed
18+
- name: Implementation
19+
status: in_progress
20+
progress: 62
21+
artifacts:
22+
product_brief:
23+
path: bmad/artifacts/product-brief.md
24+
status: completed
25+
prd:
26+
path: bmad/artifacts/prd.md
27+
status: completed
28+
tech_spec:
29+
path: bmad/artifacts/tech-spec.md
30+
status: completed
31+
architecture:
32+
path: bmad/artifacts/architecture.md
33+
status: completed
34+
marketing_brief:
35+
path: bmad/artifacts/marketing-brief.md
36+
status: drafted
37+
connector:
38+
path: bmad/artifacts/connector.yml
39+
status: generated
40+
audit:
41+
last_run: "2026-03-05"
42+
type: "full"
43+
baseline: true
44+
score: 76
45+
project_type: "single-package"
46+
packages_scanned: ["."]
47+
critical: 0
48+
major: 2
49+
minor: 4
50+
info: 3
51+
artifact: "bmad/artifacts/audit-baseline-2026-03-05.md"
52+
auto_stories_created: []
53+
qa:
54+
test_plan: null
55+
coverage: null
56+
last_run: null
57+
bugs: []
58+
sprints: []
59+
backlog: []
60+
recommendation: "bmad dashboard"
61+
dashboard:
62+
last_generated: "2026-03-05"
63+
master_generated: false
64+
connector_generated: true
Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
version: 1
2+
project:
3+
name: rustine
4+
type: single-package
5+
stack:
6+
- Rust 2021
7+
- Dioxus Desktop
8+
- SQLite (rusqlite bundled)
9+
- Tailwind CSS (pnpm)
10+
- Reqwest (blocking)
11+
phases:
12+
- name: Analysis
13+
status: completed
14+
- name: Planning
15+
status: completed
16+
- name: Solutioning
17+
status: completed
18+
- name: Implementation
19+
status: in_progress
20+
progress: 62
21+
artifacts:
22+
product_brief:
23+
path: bmad/artifacts/product-brief-webapp.md
24+
status: completed
25+
prd:
26+
path: bmad/artifacts/prd-webapp.md
27+
status: completed
28+
tech_spec:
29+
path: bmad/artifacts/tech-spec.md
30+
status: completed
31+
architecture:
32+
path: bmad/artifacts/architecture.md
33+
status: completed
34+
marketing_brief:
35+
path: bmad/artifacts/marketing-brief.md
36+
status: drafted
37+
connector:
38+
path: bmad/artifacts/connector.yml
39+
status: generated
40+
audit:
41+
last_run: "2026-03-05"
42+
type: "full"
43+
baseline: true
44+
score: 76
45+
project_type: "single-package"
46+
packages_scanned: ["."]
47+
critical: 0
48+
major: 2
49+
minor: 4
50+
info: 3
51+
artifact: "bmad/artifacts/audit-baseline-2026-03-05.md"
52+
auto_stories_created: []
53+
qa:
54+
test_plan: null
55+
coverage: null
56+
last_run: null
57+
bugs: []
58+
sprints: []
59+
backlog: []
60+
recommendation: "bmad dashboard"
61+
dashboard:
62+
last_generated: "2026-03-07T16:42:38Z"
63+
master_generated: false
64+
connector_generated: true

0 commit comments

Comments
 (0)