ariadna 1.1.3 → 1.1.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/data/agents/ariadna-backend-executor.md +1 -1
- data/data/agents/ariadna-planner.md +1 -1
- data/data/agents/ariadna-test-executor.md +1 -1
- data/data/ariadna/templates/codebase/architecture.md +3 -9
- data/data/ariadna/templates/codebase/concerns.md +2 -2
- data/data/ariadna/templates/codebase/conventions.md +1 -1
- data/data/ariadna/templates/codebase/stack.md +1 -2
- data/data/ariadna/templates/research-project/ARCHITECTURE.md +60 -1
- data/data/ariadna/templates/research-project/PITFALLS.md +51 -2
- data/data/ariadna/templates/research-project/STACK.md +23 -22
- data/data/ariadna/templates/research-project/SUMMARY.md +2 -2
- data/data/guides/backend.md +5 -52
- data/data/templates.md +2 -2
- data/lib/ariadna/tools/config_manager.rb +1 -0
- data/lib/ariadna/tools/phase_manager.rb +1 -0
- data/lib/ariadna/version.rb +1 -1
- metadata +1 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: b216fcd72bc73121f1c9129c55c7575ddf50d0ff0d14f34e14f34398a3c6aa23
|
|
4
|
+
data.tar.gz: 04bad2627d8928f2c2a641f67366764f6d5336ef17fae933923633b675cbd41d
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 20e330e4c9ca1c1b7bb149efbe12446800c00dd80d6cb299cb38fa1f285244ac05f0b577f196dfa658492c71df5cf697df01885f395998c271008c2e48d105ce
|
|
7
|
+
data.tar.gz: 2c449bfa9ba635500167fac1019c047559938f89cc8adbfb958e88bb2ea6bf9e3e148b54d62a7d208dfbb6b091b9a53d558406651fc733fc5093689386cb7898
|
|
@@ -23,7 +23,7 @@ Load and follow the project's backend guide for domain-specific patterns:
|
|
|
23
23
|
- **Models & Concerns:** Concern-driven architecture, intention-revealing APIs, smart association defaults
|
|
24
24
|
- **Controllers:** Thin controllers delegating to rich models, RESTful resource nesting
|
|
25
25
|
- **Jobs:** Ultra-thin jobs with _now/_later pattern, multi-tenancy context
|
|
26
|
-
- **Migrations:**
|
|
26
|
+
- **Migrations:** Proper foreign key references
|
|
27
27
|
- **Configuration:** Rails conventions, initializers, routing
|
|
28
28
|
|
|
29
29
|
**When executing backend tasks:**
|
|
@@ -180,7 +180,7 @@ Each task: **15-60 minutes** Claude execution time.
|
|
|
180
180
|
| "Create the API" | "Create POST /projects endpoint in ProjectsController#create accepting {name, description}, validates name length 3-50 chars, returns 201 with project JSON" |
|
|
181
181
|
| "Style the dashboard" | "Add CSS classes to dashboard view: grid layout (3 cols on lg via media query, 1 on mobile), card shadows via --shadow variable, hover states on action buttons per style guide" |
|
|
182
182
|
| "Handle errors" | "Add rescue_from in ApplicationController, render JSON errors on 4xx/5xx, show flash messages on server-rendered pages" |
|
|
183
|
-
| "Set up the database" | "Add User and Project models
|
|
183
|
+
| "Set up the database" | "Add User and Project models, email unique constraint, timestamps, run rails db:migrate" |
|
|
184
184
|
|
|
185
185
|
**Test:** Could a different Claude instance execute without asking clarifying questions? If not, add specificity.
|
|
186
186
|
|
|
@@ -21,7 +21,7 @@ Load and follow the project's testing guide for domain-specific patterns:
|
|
|
21
21
|
|
|
22
22
|
**Focus areas:**
|
|
23
23
|
- **Minitest conventions:** `ActiveSupport::TestCase` for models, `ActionDispatch::IntegrationTest` for controllers
|
|
24
|
-
- **Fixtures:** YAML fixtures for deterministic test data
|
|
24
|
+
- **Fixtures:** YAML fixtures for deterministic test data
|
|
25
25
|
- **Current context:** Always set `Current.session = sessions(:name)` in setup blocks
|
|
26
26
|
- **assert_difference:** Use for state changes, nest for multiple record types
|
|
27
27
|
- **Testing patterns:** Model tests for business logic, controller tests for delegation, job tests for enqueuing
|
|
@@ -17,7 +17,7 @@ Template for `.planning/codebase/ARCHITECTURE.md` - captures conceptual code org
|
|
|
17
17
|
|
|
18
18
|
**Overall:** [Pattern name: e.g., "Rails Monolith", "Rails API-only", "Rails + Hotwire", "Rails Engine-based"]
|
|
19
19
|
|
|
20
|
-
**Multi-Tenancy:** [e.g., "Path-based with CurrentAttributes", "Subdomain-based", "
|
|
20
|
+
**Multi-Tenancy:** [e.g., "Path-based with CurrentAttributes", "Subdomain-based", "session based", "Single-tenant", "None"]
|
|
21
21
|
|
|
22
22
|
**Key Characteristics:**
|
|
23
23
|
- [Characteristic 1: e.g., "Server-rendered with Turbo"]
|
|
@@ -277,7 +277,7 @@ Template for `.planning/codebase/ARCHITECTURE.md` - captures conceptual code org
|
|
|
277
277
|
**Key Domain Models:**
|
|
278
278
|
- `Account` — Tenant root. All data scoped to an account
|
|
279
279
|
- `Board` — Project workspace containing cards, columns, and access rules
|
|
280
|
-
- `Card` — Primary work item. Most concern-composed model (20+ concerns).
|
|
280
|
+
- `Card` — Primary work item. Most concern-composed model (20+ concerns).
|
|
281
281
|
- `Event` — Audit trail record. Polymorphic `eventable`, JSON `particulars` for action-specific data
|
|
282
282
|
- `User` — Account member with role-based permissions. Resolved from `Current.session` → `identity` → `user`
|
|
283
283
|
|
|
@@ -357,11 +357,6 @@ Template for `.planning/codebase/ARCHITECTURE.md` - captures conceptual code org
|
|
|
357
357
|
- Location: `app/models/` subdirectories — `User::Filtering`, `Event::Description`, `User::DayTimeline`
|
|
358
358
|
- Pattern: Constructor injection, memoized collections (`@boards ||= ...`), boolean methods for conditional display (`show_tags?`), cache keys for fragment caching. Some include `ActionView::Helpers::TagHelper` for HTML generation. Instantiated via controller concerns or factory methods on models (`event.description_for(user)`)
|
|
359
359
|
|
|
360
|
-
**Pundit Policies:**
|
|
361
|
-
- Purpose: Authorize user actions on resources
|
|
362
|
-
- Examples: `ProjectPolicy`, `TaskPolicy`, `MembershipPolicy`
|
|
363
|
-
- Pattern: Policy class per model with `?` predicate methods
|
|
364
|
-
|
|
365
360
|
## Multi-Tenancy & Current Context
|
|
366
361
|
|
|
367
362
|
**Approach:** Path-based — account slug extracted from URL path by `AccountSlug::Extractor` middleware. Slug moves from `PATH_INFO` to `SCRIPT_NAME`. No subdomain configuration needed.
|
|
@@ -400,7 +395,7 @@ Template for `.planning/codebase/ARCHITECTURE.md` - captures conceptual code org
|
|
|
400
395
|
|
|
401
396
|
**Patterns:**
|
|
402
397
|
- `rescue_from ActiveRecord::RecordNotFound` → 404 page
|
|
403
|
-
- `rescue_from
|
|
398
|
+
- `rescue_from NotAuthorizedError` → 403 or redirect with flash
|
|
404
399
|
- Model validation errors re-render form with `@model.errors`
|
|
405
400
|
- Service objects return `Result` structs (success/failure) instead of raising
|
|
406
401
|
- Jobs use `retry_on` for transient failures, `discard_on` for permanent ones
|
|
@@ -421,7 +416,6 @@ Template for `.planning/codebase/ARCHITECTURE.md` - captures conceptual code org
|
|
|
421
416
|
- `require_authentication` filter on all non-public controllers
|
|
422
417
|
|
|
423
418
|
**Authorization:**
|
|
424
|
-
- Pundit policies per resource
|
|
425
419
|
- `authorize` calls in controller actions
|
|
426
420
|
- Scoped queries via `policy_scope`
|
|
427
421
|
|
|
@@ -190,8 +190,8 @@ Template for `.planning/codebase/CONCERNS.md` - captures known issues and areas
|
|
|
190
190
|
**Missing authorization checks on nested resources:**
|
|
191
191
|
- Risk: Card comments endpoint does not verify user has access to the parent board
|
|
192
192
|
- Files: `app/controllers/comments_controller.rb`, missing `authorize @comment` call
|
|
193
|
-
- Current mitigation:
|
|
194
|
-
- Recommendations: Add
|
|
193
|
+
- Current mitigation: Denormalise tables so all include account_id and rely on `Current.account` scope, but no explicit check on board access.
|
|
194
|
+
- Recommendations: Add `before_action` scope check.
|
|
195
195
|
|
|
196
196
|
**Unscoped queries leaking tenant data:**
|
|
197
197
|
- Risk: `Admin::ReportsController` uses `Card.where(created_at: range)` without `Current.account` scope
|
|
@@ -251,7 +251,7 @@ end
|
|
|
251
251
|
- Model validation errors re-render form with `@model.errors`
|
|
252
252
|
|
|
253
253
|
**Error Types:**
|
|
254
|
-
- Raise on authorization failures: `rescue_from
|
|
254
|
+
- Raise on authorization failures: `rescue_from NotAuthorizedError`
|
|
255
255
|
- Raise on missing records: `rescue_from ActiveRecord::RecordNotFound`
|
|
256
256
|
- Return `false`/`nil` for expected domain failures
|
|
257
257
|
- Jobs: `retry_on` for transient failures (network, timeouts), `discard_on ActiveRecord::RecordNotFound`
|
|
@@ -123,9 +123,8 @@ Template for `.planning/codebase/STACK.md` - captures the technology foundation.
|
|
|
123
123
|
|
|
124
124
|
**Critical:**
|
|
125
125
|
- authentication (built-in) — Session-based auth
|
|
126
|
-
-
|
|
126
|
+
- authorization - custom implementation (no gem) — Role-based access control, pundit
|
|
127
127
|
- solid_queue — Background jobs (Rails 8 default)
|
|
128
|
-
- stripe — Payment processing
|
|
129
128
|
|
|
130
129
|
**Infrastructure:**
|
|
131
130
|
- sqlite3 — SQLite adapter (Rails default)
|
|
@@ -164,7 +164,57 @@ test/ # [test framework: Minitest (default) or spec/ if RSp
|
|
|
164
164
|
### Authentication and Authorization
|
|
165
165
|
|
|
166
166
|
**Authentication:** [Rails authentication generator / has_secure_password / custom / other]
|
|
167
|
-
**Authorization:** [
|
|
167
|
+
**Authorization:** [Custom / Pundit / CanCanCan / Action Policy / other]
|
|
168
|
+
|
|
169
|
+
### Internationalization (I18n)
|
|
170
|
+
|
|
171
|
+
**Configuration:**
|
|
172
|
+
- Default locale: [discovered from `config.i18n.default_locale`]
|
|
173
|
+
- Available locales: [discovered from `config.i18n.available_locales`]
|
|
174
|
+
- Fallback chain: [discovered from `config.i18n.fallbacks`]
|
|
175
|
+
|
|
176
|
+
**Locale file organization:**
|
|
177
|
+
```
|
|
178
|
+
config/locales/
|
|
179
|
+
├── [default locale].yml # [application-wide defaults]
|
|
180
|
+
├── activerecord.[lang].yml # [model and attribute translations]
|
|
181
|
+
├── [feature].[lang].yml # [per-feature locale files if present]
|
|
182
|
+
└── [additional locale files discovered]
|
|
183
|
+
```
|
|
184
|
+
|
|
185
|
+
**ActiveRecord translations:**
|
|
186
|
+
```yaml
|
|
187
|
+
# config/locales/activerecord.[lang].yml
|
|
188
|
+
[lang]:
|
|
189
|
+
activerecord:
|
|
190
|
+
models:
|
|
191
|
+
[model]: [translated model name]
|
|
192
|
+
attributes:
|
|
193
|
+
[model]:
|
|
194
|
+
[attribute]: [translated attribute name]
|
|
195
|
+
```
|
|
196
|
+
|
|
197
|
+
**Translation approach:**
|
|
198
|
+
|
|
199
|
+
| Context | Recommended Approach | What This Project Does |
|
|
200
|
+
|---------|---------------------|------------------------|
|
|
201
|
+
| Model names | `activerecord.models.*` — automatic lookup by Rails | [discovered approach] |
|
|
202
|
+
| Attribute names | `activerecord.attributes.*` — automatic lookup by `form.label`, validations, etc. | [discovered approach] |
|
|
203
|
+
| Form labels | `form.label :name` — resolves from `activerecord.attributes` automatically | [discovered approach] |
|
|
204
|
+
| Validation messages | `activerecord.errors.models.*` / `errors.messages.*` — automatic lookup | [discovered approach] |
|
|
205
|
+
| View text | Lazy lookup `t(".title")` or explicit `t("views.controller.action.title")` | [discovered approach] |
|
|
206
|
+
| Enum values | `activerecord.attributes.[model].[enum_attribute]/[value]` | [discovered approach] |
|
|
207
|
+
| Flash messages | Controller lazy lookup `t(".success")` or explicit keys | [discovered approach] |
|
|
208
|
+
| Mailer subjects | `I18n.t("mailer_name.action_name.subject")` — automatic from mailer class | [discovered approach] |
|
|
209
|
+
|
|
210
|
+
**CLDR / base locale data:**
|
|
211
|
+
- `rails-i18n` gem: [present/absent — provides date, time, currency, number formats for non-English locales]
|
|
212
|
+
- Custom date/time formats: [discovered in locale files or initializers]
|
|
213
|
+
|
|
214
|
+
**Example from codebase:**
|
|
215
|
+
```ruby
|
|
216
|
+
# [Brief code example showing the project's actual I18n usage pattern]
|
|
217
|
+
```
|
|
168
218
|
|
|
169
219
|
## Data Flow
|
|
170
220
|
|
|
@@ -377,4 +427,13 @@ Client receives → DOM update
|
|
|
377
427
|
- Note external API integration patterns and HTTP client choices
|
|
378
428
|
- Look for engine boundaries and module interfaces
|
|
379
429
|
|
|
430
|
+
**Internationalization (I18n):**
|
|
431
|
+
- Check `config/application.rb` for `i18n.default_locale`, `i18n.available_locales`, and `i18n.fallbacks`
|
|
432
|
+
- Inspect `config/locales/` file organization — per-model, per-feature, or flat structure
|
|
433
|
+
- Look for `activerecord.models.*` and `activerecord.attributes.*` keys in locale files — these power automatic lookup for model names, form labels, and validation messages
|
|
434
|
+
- Check whether form labels use automatic lookup (`form.label :name`) vs explicit `t()` calls — explicit calls duplicate what Rails provides for free
|
|
435
|
+
- Check Gemfile for `rails-i18n` gem — provides CLDR base data (dates, times, currency, numbers) for non-English locales
|
|
436
|
+
- Look for validation error message customization under `activerecord.errors.models.*`
|
|
437
|
+
- Check for lazy lookup usage in views (`t(".key")`) and controllers
|
|
438
|
+
|
|
380
439
|
</guidelines>
|
|
@@ -155,7 +155,7 @@ params.require(:user).permit(:name, :email)
|
|
|
155
155
|
[Root cause — e.g., tenant scoping not enforced at the framework level, new developers unaware of scoping requirements, background jobs not carrying tenant context]
|
|
156
156
|
|
|
157
157
|
**How to avoid:**
|
|
158
|
-
[Prevention strategy — e.g.,
|
|
158
|
+
[Prevention strategy — e.g., Current attributes for tenant context, controller-level `around_action` for scoping, test isolation per tenant]
|
|
159
159
|
|
|
160
160
|
**Warning signs:**
|
|
161
161
|
[How to detect early — e.g., queries without `WHERE tenant_id = ?`, cross-tenant data appearing in tests, background jobs processing wrong tenant data]
|
|
@@ -184,6 +184,53 @@ params.require(:user).permit(:name, :email)
|
|
|
184
184
|
|
|
185
185
|
---
|
|
186
186
|
|
|
187
|
+
### Pitfall 7: Explicit Translation Keys Instead of ActiveRecord Automatic Lookup
|
|
188
|
+
|
|
189
|
+
**What goes wrong:**
|
|
190
|
+
[Describe where explicit `t()` calls duplicate what Rails I18n automatic lookup provides — e.g., form labels passing explicit keys, validation messages hardcoded, model names translated manually]
|
|
191
|
+
|
|
192
|
+
**Why it happens:**
|
|
193
|
+
[Root cause — e.g., developers unaware of ActiveRecord I18n conventions, copying patterns from non-Rails projects, not reading Rails I18n guide]
|
|
194
|
+
|
|
195
|
+
**How to avoid:**
|
|
196
|
+
[Prevention strategy — e.g., use `form.label :name` instead of `form.label :name, t("teams.form.name")`, define translations under `activerecord.attributes.*` and `activerecord.models.*`, rely on automatic lookup for validation messages]
|
|
197
|
+
|
|
198
|
+
**Warning signs:**
|
|
199
|
+
[How to detect early — e.g., duplicate translation keys for the same attribute in different namespaces, inconsistent labels between forms and error messages, `t()` calls in form labels that mirror `activerecord.attributes` keys]
|
|
200
|
+
|
|
201
|
+
**Example:**
|
|
202
|
+
```ruby
|
|
203
|
+
# Bad — explicit key duplicates what Rails provides automatically
|
|
204
|
+
<%= form.label :name, t("teams.form.name") %>
|
|
205
|
+
# Requires: teams.form.name in locale file AND activerecord.attributes.team.name for validations
|
|
206
|
+
|
|
207
|
+
# Good — resolves from activerecord.attributes.team.name automatically
|
|
208
|
+
<%= form.label :name %>
|
|
209
|
+
# Single source of truth: activerecord.attributes.team.name used by forms AND validations
|
|
210
|
+
```
|
|
211
|
+
|
|
212
|
+
```yaml
|
|
213
|
+
# Good — single source of truth for attribute names
|
|
214
|
+
en:
|
|
215
|
+
activerecord:
|
|
216
|
+
models:
|
|
217
|
+
team: "Team"
|
|
218
|
+
attributes:
|
|
219
|
+
team:
|
|
220
|
+
name: "Team name"
|
|
221
|
+
errors:
|
|
222
|
+
models:
|
|
223
|
+
team:
|
|
224
|
+
attributes:
|
|
225
|
+
name:
|
|
226
|
+
blank: "cannot be empty"
|
|
227
|
+
```
|
|
228
|
+
|
|
229
|
+
**Phase to address:**
|
|
230
|
+
[Which roadmap phase should prevent this]
|
|
231
|
+
|
|
232
|
+
---
|
|
233
|
+
|
|
187
234
|
[Continue for additional critical pitfalls specific to this application...]
|
|
188
235
|
|
|
189
236
|
## Technical Debt Patterns
|
|
@@ -215,6 +262,7 @@ Common mistakes when integrating Rails gems and external services.
|
|
|
215
262
|
| Turbo / Hotwire | [e.g., full page reloads from misconfigured frames, missing turbo stream responses, form submission edge cases] | [what to do instead] |
|
|
216
263
|
| Rails version upgrades | [e.g., skipping deprecation warnings, upgrading multiple major versions at once, not running `rails app:update`] | [what to do instead] |
|
|
217
264
|
| Third-party APIs | [e.g., no circuit breaker, synchronous calls in request cycle, no webhook signature verification] | [what to do instead] |
|
|
265
|
+
| I18n / rails-i18n | [e.g., using explicit `t()` keys for model attributes and form labels instead of ActiveRecord automatic lookup, missing `rails-i18n` gem for CLDR data (dates, currency, numbers), inconsistent locale file organization mixing per-model and flat structures] | [e.g., define translations under `activerecord.attributes.*` and `activerecord.models.*`, use `form.label :field` without explicit `t()`, add `rails-i18n` gem for base locale data, organize locale files consistently] |
|
|
218
266
|
| [integration] | [what people do wrong] | [what to do instead] |
|
|
219
267
|
|
|
220
268
|
## Performance Traps
|
|
@@ -241,7 +289,7 @@ Rails-specific security issues beyond basic web security.
|
|
|
241
289
|
| SQL injection via string interpolation in `where` | [e.g., user input directly in query string allows data exfiltration] | [e.g., always use parameterized queries: `where("name = ?", params[:name])` or hash syntax `where(name: params[:name])`] |
|
|
242
290
|
| CSRF token handling gaps | [e.g., API endpoints without `protect_from_forgery`, token not verified on state-changing requests] | [e.g., `protect_from_forgery with: :exception`, proper token handling for JS requests, `csrf_meta_tags` in layout] |
|
|
243
291
|
| Credential management mistakes | [e.g., secrets in ENV vars without encryption, credentials checked into git, different credentials per environment not managed] | [e.g., Rails encrypted credentials, `rails credentials:edit`, per-environment credential files] |
|
|
244
|
-
| Insecure direct object references | [e.g., `User.find(params[:id])` without authorization check, enumerable IDs exposing records] | [e.g., always scope to authorized records: `current_user.posts.find(params[:id])`, use
|
|
292
|
+
| Insecure direct object references | [e.g., `User.find(params[:id])` without authorization check, enumerable IDs exposing records] | [e.g., always scope to authorized records: `current_user.posts.find(params[:id])`, use Current.account or Current.employee] |
|
|
245
293
|
| Mass assignment vulnerabilities | [e.g., unpermitted nested attributes modifying admin fields, `accepts_nested_attributes_for` without `reject_if`] | [e.g., explicit strong parameters, test that admin attributes cannot be set via API, `attr_readonly` for sensitive fields] |
|
|
246
294
|
| Unsafe `html_safe` / `raw` usage | [e.g., XSS from marking user input as safe, rendering unescaped HTML from database] | [e.g., never call `html_safe` on user input, use `sanitize` helper, Content Security Policy headers] |
|
|
247
295
|
| Open redirects | [e.g., `redirect_to params[:return_to]` allows redirecting to malicious sites] | [e.g., validate redirect URLs against allowlist, use `redirect_back` with `fallback_location`] |
|
|
@@ -261,6 +309,7 @@ Rails features that appear complete but are missing critical pieces.
|
|
|
261
309
|
- [ ] **Database connection pooling:** Pool size matches worker/thread count — verify `database.yml` pool matches Puma thread count
|
|
262
310
|
- [ ] **Timezone handling:** Application uses `Time.current` / `Date.current` instead of `Time.now` / `Date.today` — verify `config.time_zone` is set and used consistently
|
|
263
311
|
- [ ] **Email delivery:** Mailers use `deliver_later` not `deliver_now` in web requests — verify mailer calls don't block request cycle
|
|
312
|
+
- [ ] **I18n locale completeness:** All supported locales have matching keys for `activerecord.models.*`, `activerecord.attributes.*`, and `activerecord.errors.*` — verify with `i18n-tasks` gem or manual comparison that no locale is missing translations present in others
|
|
264
313
|
- [ ] **[Feature]:** Often missing [thing] — verify [check]
|
|
265
314
|
- [ ] **[Feature]:** Often missing [thing] — verify [check]
|
|
266
315
|
|
|
@@ -52,13 +52,14 @@ Template for `.planning/research/STACK.md` — discovered technology stack for t
|
|
|
52
52
|
| File storage service | [local/S3/GCS/Azure/none] | [config/storage.yml] |
|
|
53
53
|
| Email | [Action Mailer/Postmark/SendGrid/none] | [Gemfile, mailer configs] |
|
|
54
54
|
| PDF generation | [Prawn/wicked_pdf/Grover/none] | [Gemfile] |
|
|
55
|
+
| Internationalization | [rails-i18n gem / manual locale files only / none] | [Gemfile, config/locales/] |
|
|
55
56
|
|
|
56
57
|
## Authentication & Authorization
|
|
57
58
|
|
|
58
59
|
| Category | Discovered Value | Evidence |
|
|
59
60
|
|----------|-----------------|----------|
|
|
60
61
|
| Authentication | [Rails authentication generator/Rodauth/Clearance/custom/none] | [Gemfile, user model] |
|
|
61
|
-
| Authorization | [Pundit/CanCanCan/Action Policy/
|
|
62
|
+
| Authorization | [Custom/Pundit/CanCanCan/Action Policy/none] | [Gemfile, policy files] |
|
|
62
63
|
| OAuth/social login | [OmniAuth/Doorkeeper/none] | [Gemfile, initializers] |
|
|
63
64
|
| API authentication | [API tokens/JWT/OAuth2/none] | [Gemfile, controller concerns] |
|
|
64
65
|
|
|
@@ -209,38 +210,38 @@ bin/rails server
|
|
|
209
210
|
- Look at `database.yml` for multiple database configurations
|
|
210
211
|
|
|
211
212
|
**Frontend & Assets:**
|
|
212
|
-
- Check for `config/importmap.rb` (Importmap), `package.json` (Node-based), or `vite.config.ts` (Vite)
|
|
213
|
-
- Look at `app/views/layouts/application.html.erb` for asset tags
|
|
214
|
-
- Check `app/javascript/` structure and `app/assets/` for CSS approach
|
|
215
|
-
- Look for `app/components/` (ViewComponent) or Phlex usage
|
|
213
|
+
- Check for `config/importmap.rb` (Importmap), `package.json` (Node-based), or `vite.config.ts` (Vite).
|
|
214
|
+
- Look at `app/views/layouts/application.html.erb` for asset tags.
|
|
215
|
+
- Check `app/javascript/` structure and `app/assets/` for CSS approach.
|
|
216
|
+
- Look for `app/components/` (ViewComponent) or Phlex usage.
|
|
216
217
|
|
|
217
218
|
**Backend Services:**
|
|
218
|
-
- Check `config/application.rb` for `active_job.queue_adapter` setting
|
|
219
|
-
- Check `config/environments/production.rb` for cache store configuration
|
|
220
|
-
- Look at `config/cable.yml` for Action Cable adapter
|
|
221
|
-
- Check `config/storage.yml` for Active Storage service
|
|
219
|
+
- Check `config/application.rb` for `active_job.queue_adapter` setting.
|
|
220
|
+
- Check `config/environments/production.rb` for cache store configuration.
|
|
221
|
+
- Look at `config/cable.yml` for Action Cable adapter.
|
|
222
|
+
- Check `config/storage.yml` for Active Storage service.
|
|
222
223
|
|
|
223
224
|
**Authentication & Authorization:**
|
|
224
|
-
- Look for `Authentication` concern generated by `rails generate authentication
|
|
225
|
-
- Look for `app/policies/` (Pundit) or `app/models/ability.rb` (CanCanCan)
|
|
226
|
-
- Check `app/models/user.rb` for authentication modules
|
|
225
|
+
- Look for `Authentication` concern generated by `rails generate authentication`.
|
|
226
|
+
- Look for `app/policies/` (Pundit) or `app/models/ability.rb` (CanCanCan) or custom authorization logic.
|
|
227
|
+
- Check `app/models/user.rb` for authentication modules.
|
|
227
228
|
|
|
228
229
|
**Testing:**
|
|
229
230
|
- Determine framework: check for `test/` (Minitest, recommended) vs `spec/` (RSpec)
|
|
230
|
-
- Check `test/test_helper.rb` (Minitest) or `spec/rails_helper.rb` (if RSpec) for test configuration
|
|
231
|
-
- Look for `test/fixtures/` or `spec/factories/` to determine data strategy
|
|
232
|
-
- Check for system test configuration and browser driver
|
|
231
|
+
- Check `test/test_helper.rb` (Minitest) or `spec/rails_helper.rb` (if RSpec) for test configuration.
|
|
232
|
+
- Look for `test/fixtures/` or `spec/factories/` to determine data strategy.
|
|
233
|
+
- Check for system test configuration and browser driver.
|
|
233
234
|
|
|
234
235
|
**What to Avoid:**
|
|
235
|
-
- Flag gems that are no longer maintained or have known security issues
|
|
236
|
-
- Note deprecated Rails patterns found in the codebase (e.g., `before_filter`, `attr_accessible`)
|
|
237
|
-
- Identify gems that duplicate Rails built-in functionality unnecessarily
|
|
238
|
-
- Flag any gems with known incompatibilities with the discovered Rails version
|
|
236
|
+
- Flag gems that are no longer maintained or have known security issues.
|
|
237
|
+
- Note deprecated Rails patterns found in the codebase (e.g., `before_filter`, `attr_accessible`).
|
|
238
|
+
- Identify gems that duplicate Rails built-in functionality unnecessarily.
|
|
239
|
+
- Flag any gems with known incompatibilities with the discovered Rails version.
|
|
239
240
|
|
|
240
241
|
**Gem Inventory:**
|
|
241
|
-
- Record version constraints as written in the Gemfile, not resolved versions
|
|
242
|
-
- Note which Bundler group each gem belongs to
|
|
243
|
-
- For important gems, check if the version is current or significantly outdated
|
|
242
|
+
- Record version constraints as written in the Gemfile, not resolved versions.
|
|
243
|
+
- Note which Bundler group each gem belongs to.
|
|
244
|
+
- For important gems, check if the version is current or significantly outdated.
|
|
244
245
|
|
|
245
246
|
**Version Compatibility:**
|
|
246
247
|
- Note any gems that pin to specific Rails or Ruby versions
|
|
@@ -53,7 +53,7 @@ Template for `.planning/research/SUMMARY.md` — executive summary of project re
|
|
|
53
53
|
|
|
54
54
|
**Authentication & authorization:**
|
|
55
55
|
- [Auth solution]: [purpose] — [why recommended — e.g., Rails authentication generator for session-based auth]
|
|
56
|
-
- [Authorization]: [purpose] — [why recommended — e.g., Pundit for policies, Action Policy for scalable rules]
|
|
56
|
+
- [Authorization]: [purpose] — [why recommended — e.g., before_action, Pundit for policies, Action Policy for scalable rules]
|
|
57
57
|
|
|
58
58
|
**Additional gems:**
|
|
59
59
|
- [Gem]: [purpose] — [why recommended]
|
|
@@ -87,7 +87,7 @@ Template for `.planning/research/SUMMARY.md` — executive summary of project re
|
|
|
87
87
|
6. [Data access patterns] — [approach — e.g., scopes, query objects, eager loading strategy]
|
|
88
88
|
|
|
89
89
|
**Multi-tenancy approach (if applicable):**
|
|
90
|
-
- [Strategy] — [e.g.,
|
|
90
|
+
- [Strategy] — [e.g., Denormalise tables with account_id and use Current.account, PostgreSQL schemas, separate databases]
|
|
91
91
|
|
|
92
92
|
**Engine extraction (if applicable):**
|
|
93
93
|
- [Engine/mountable concern] — [e.g., admin engine, API engine, shared authentication engine]
|
data/data/guides/backend.md
CHANGED
|
@@ -18,7 +18,6 @@ We stand on the shoulders of giants.
|
|
|
18
18
|
- [Part 1: Foundation & Architecture](#part-1-foundation--architecture)
|
|
19
19
|
- [1.0 The Vanilla Rails Philosophy](#10-the-vanilla-rails-philosophy)
|
|
20
20
|
- [1.1 Understanding Architecture](#11-understanding-fizzys-architecture)
|
|
21
|
-
- [1.2 UUID Primary Keys & Fixtures](#12-uuid-primary-keys--fixtures)
|
|
22
21
|
- [Part 2: Model Layer Patterns](#part-2-model-layer-patterns)
|
|
23
22
|
- [2.1 Concern Architecture](#21-concern-architecture)
|
|
24
23
|
- [2.2 Intention-Revealing APIs](#22-intention-revealing-apis)
|
|
@@ -204,52 +203,6 @@ setup do
|
|
|
204
203
|
end
|
|
205
204
|
```
|
|
206
205
|
|
|
207
|
-
### UUID Primary Keys
|
|
208
|
-
|
|
209
|
-
It uses UUIDs (UUIDv7, base36-encoded to 25 characters) instead of auto-incrementing integers:
|
|
210
|
-
|
|
211
|
-
**Why UUIDs:**
|
|
212
|
-
- **Security**: No ID enumeration across tenants
|
|
213
|
-
- **Distributed systems**: Can generate IDs client-side
|
|
214
|
-
- **Merging**: No ID conflicts when combining data
|
|
215
|
-
|
|
216
|
-
**The Card exception**: Cards use `number` (integer) for user-facing IDs:
|
|
217
|
-
```ruby
|
|
218
|
-
# Card ID: "abc123def456..." (UUID, internal)
|
|
219
|
-
# Card number: 1234 (integer, user-facing)
|
|
220
|
-
|
|
221
|
-
# In routes and URLs
|
|
222
|
-
card_path(@card) # => /cards/1234 (uses number, not ID)
|
|
223
|
-
|
|
224
|
-
# In controllers
|
|
225
|
-
@card = Current.user.accessible_cards.find_by!(number: params[:id])
|
|
226
|
-
```
|
|
227
|
-
|
|
228
|
-
**Fixture behavior:**
|
|
229
|
-
- Fixture UUIDs are deterministic and always "older" than test-created records
|
|
230
|
-
- `.first` and `.last` work predictably in tests
|
|
231
|
-
|
|
232
|
-
## 1.2 UUID Primary Keys & Fixtures
|
|
233
|
-
|
|
234
|
-
### Practical Implications
|
|
235
|
-
|
|
236
|
-
```ruby
|
|
237
|
-
# ✓ Good: Find cards by number
|
|
238
|
-
def set_card
|
|
239
|
-
@card = Current.user.accessible_cards.find_by!(number: params[:id])
|
|
240
|
-
end
|
|
241
|
-
|
|
242
|
-
# ✗ Bad: Don't use regular find for cards
|
|
243
|
-
def set_card
|
|
244
|
-
@card = Card.find(params[:id]) # Wrong! Cards use number for params
|
|
245
|
-
end
|
|
246
|
-
|
|
247
|
-
# ✓ Good: Everything else uses UUID find
|
|
248
|
-
def set_board
|
|
249
|
-
@board = Current.user.boards.find(params[:board_id])
|
|
250
|
-
end
|
|
251
|
-
```
|
|
252
|
-
|
|
253
206
|
---
|
|
254
207
|
|
|
255
208
|
# Part 2: Model Layer Patterns
|
|
@@ -2642,10 +2595,10 @@ end
|
|
|
2642
2595
|
```ruby
|
|
2643
2596
|
class CreateCardArchives < ActiveRecord::Migration[7.1]
|
|
2644
2597
|
def change
|
|
2645
|
-
create_table :card_archives
|
|
2646
|
-
t.references :card, null: false, foreign_key: true
|
|
2647
|
-
t.references :user, null: false, foreign_key: true
|
|
2648
|
-
t.references :account, null: false, foreign_key: true
|
|
2598
|
+
create_table :card_archives do |t|
|
|
2599
|
+
t.references :card, null: false, foreign_key: true
|
|
2600
|
+
t.references :user, null: false, foreign_key: true
|
|
2601
|
+
t.references :account, null: false, foreign_key: true
|
|
2649
2602
|
t.timestamps
|
|
2650
2603
|
end
|
|
2651
2604
|
end
|
|
@@ -3094,7 +3047,7 @@ Wrap related operations in transactions.
|
|
|
3094
3047
|
|
|
3095
3048
|
This documentation covers the core backend patterns and practices used throughout the Rails application:
|
|
3096
3049
|
|
|
3097
|
-
- **Foundation**: Multi-tenancy via Current context
|
|
3050
|
+
- **Foundation**: Multi-tenancy via Current context
|
|
3098
3051
|
- **Models**: Concern-driven architecture, intention-revealing APIs, smart defaults
|
|
3099
3052
|
- **Controllers**: Thin controllers that delegate to rich models
|
|
3100
3053
|
- **Jobs**: Ultra-thin jobs following _now/_later pattern
|
data/data/templates.md
CHANGED
|
@@ -57,7 +57,7 @@ Launch **6 parallel agents** (one per file), each tasked with rewriting a single
|
|
|
57
57
|
- **Languages**: Ruby (version from `.ruby-version`), JavaScript/CSS for assets
|
|
58
58
|
- **Runtime**: Ruby + Bundler, `.ruby-version`
|
|
59
59
|
- **Frameworks**: Rails (version), Minitest (recommended)/RSpec, Hotwire/Turbo/Stimulus
|
|
60
|
-
- **Key Dependencies**: Key gems (solid_queue, solid_cache,
|
|
60
|
+
- **Key Dependencies**: Key gems (solid_queue, solid_cache, etc.)
|
|
61
61
|
- **Configuration**: `database.yml`, `credentials.yml.enc`, `config/environments/`
|
|
62
62
|
- **Build**: Asset pipeline (Propshaft/Sprockets), importmap/esbuild/vite
|
|
63
63
|
- **Platform**: Kamal, Docker, Heroku, etc.
|
|
@@ -79,7 +79,7 @@ Launch **6 parallel agents** (one per file), each tasked with rewriting a single
|
|
|
79
79
|
- **Organization**: `test/` mirroring `app/`, fixtures in `test/fixtures/`
|
|
80
80
|
- **Structure**: `ActiveSupport::TestCase`, `setup` blocks, `test "description"` blocks
|
|
81
81
|
- **Mocking**: `Minitest::Mock`, `stub`, `travel_to` for time
|
|
82
|
-
- **Fixtures**: YAML fixtures (Rails default),
|
|
82
|
+
- **Fixtures**: YAML fixtures (Rails default), fixture accessor methods
|
|
83
83
|
- **Test Types**: Model tests, controller tests, integration tests, system tests (Capybara)
|
|
84
84
|
- **Patterns**: `assert_difference`, `assert_changes`, `assert_no_difference`, Current context setup
|
|
85
85
|
- **Coverage**: SimpleCov
|
data/lib/ariadna/version.rb
CHANGED