axiom-accessibility
Use when fixing or auditing ANY accessibility issue — VoiceOver, Dynamic Type, color contrast, touch targets, WCAG compliance, App Store accessibility review.
Use when the user mentions database schema review, migration safety, GRDB migration audit, or SQLite schema checking.
$ npx -y skills add charleswiltgen/axiom --skill axiom-audit-database-schema --agent claude-codeHow it fires
How this skill gets triggered: by you, by Claude, or both.
/axiom-audit-database-schemaContext preview
The summary Claude sees to decide when to auto-load this skill.
Use when the user mentions database schema review, migration safety, GRDB migration audit, or SQLite schema checking.
name: axiom-audit-database-schema description: Use when the user mentions database schema review, migration safety, GRDB migration audit, or SQLite schema checking. license: MIT
You are an expert at detecting database schema and migration violations — both known anti-patterns AND missing/incomplete patterns that cause data loss, migration crashes, silent corruption, and integrity failures in SQLite/GRDB apps.
Run every Glob, Grep, and Read this prompt lists. Do not reason from training data instead of scanning.
Skip: `*Tests.swift`, `*Previews.swift`, `*/Pods/*`, `*/Carthage/*`, `*/.build/*`, `*/DerivedData/*`, `*/scratch/*`, `*/docs/*`, `*/.claude/*`, `*/.claude-plugin/*`
Glob: **/*.swift (excluding test/vendor paths) Grep for: - `import GRDB` — GRDB usage - `import SQLite` — SQLite.swift wrapper - `import StructuredQueries`, `import SQLiteData` — Point-Free's sqlite-data - `DatabasePool`, `DatabaseQueue` — GRDB connection types - `Configuration()`, `prepareDatabase` — connection configuration - `PRAGMA foreign_keys` — FK enforcement - `PRAGMA journal_mode` — WAL vs rollback
Grep for: - `DatabaseMigrator` — GRDB migrator - `registerMigration` — migration registrations - `eraseDatabaseOnSchemaChange` — destructive flag - `ALTER TABLE`, `CREATE TABLE`, `CREATE INDEX`, `DROP TABLE`, `DROP COLUMN` — raw schema DDL - `alter(table:)` with `add(column:)`, `rename(column:to:)`, `drop(column:)`, `drop(table:)` — GRDB alteration DSL - `try db.execute(sql:` — raw SQL execution
Read 2-3 key files (the migration file, the database setup file, one model file). Note:
Write a brief **Schema Map** (5-10 lines) summarizing:
Present this map in the output before proceeding.
Run all 10 detection patterns. For every grep match, use Read to verify the surrounding context before reporting — grep patterns have high recall but need contextual verification.
**Issue**: SQLite requires DEFAULT for NOT NULL columns added to existing tables. Without it, the migration crashes for any table with existing rows. **Search**: `ADD\s+COLUMN.*NOT\s+NULL` **Verify**: Read matching files; check for `DEFAULT` on the same statement. **Fix**: `ADD COLUMN name TEXT NOT NULL DEFAULT ''`
**Issue**: Permanently deletes all user data in that table. No undo. **Search**: `DROP\s+TABLE` **Verify**: Read matching files; determine if user data or temporary/scratch. **Fix**: Rename instead, or migrate data to a new table first.
**Issue**: SQLite supports DROP COLUMN from 3.35.0 (iOS 15+). On older OS the statement fails to prepare — a thrown database error, not a crash. Even where it is supported it is restricted: the column must not be a PRIMARY KEY, carry UNIQUE, be indexed, or be referenced by a trigger, view, or generated column. **Search**: `DROP\s+COLUMN`, `drop\(column:` **Fix**: Use 12-step table recreation pattern: create new, copy data, drop old, rename new.
**Issue**: `ADD COLUMN` on a column that already exists fails with "duplicate column name". A migration registered through `DatabaseMigrator` runs at most once per identifier, so this cannot happen inside `registerMigration`. The real triggers are DDL executed outside the migrator on every launch, one column added by two different migrations, and stores created by an older app version with ad-hoc schema. **Search**: `ADD\s+COLUMN`, `addColumn` **Verify**: Read matching files; check for an existence guard (`db.columns(in:)`, `PRAGMA table_info`) or a do-catch. DDL inside `registerMigration` needs no guard. **Fix**: Guard on introspection — `let exists = try db.columns(in: "users").contains { $0.name == "email" }`, then alter only when `exists` is false. `PRAGMA table_info` or a do-catch around the ALTER also works. There is no `addColumn(ifNotExists:)` in GRDB: `ifNotExists` is a creation-time option (`create(table:ifNotExists:)`, `TableOptions.ifNotExists`), and SQLite's ADD COLUMN has no such clause.
**Issue**: `INSERT OR REPLACE` deletes the old row before inserting the new one. This triggers `ON DELETE CASCADE`, silently destroying child records. **Search**: `INSERT\s+OR\s+REPLACE`, `insertOrReplace` **Verify**: Read matching files; check if target table is referenced by FK constraints. **Fix**: `INSERT ... ON CONFLICT(id) DO UPDATE SET ...` (UPSERT).
**Issue**: Foreign keys are creation-time in both SQLite and GRDB — `foreignKey(_:references:columns:onDelete:onUpdate:deferred:)` on the table definition; a `Tabl
Battle-tested skills, agents, and tools for modern Apple OS development — Swift 6, SwiftUI, Liquid Glass, Apple Intelligence, and more. Supports Claude Code, Codex, and all other popular coding harnesses and AI-savvy IDEs.
Repo: charleswiltgen/axiom
Use when fixing or auditing ANY accessibility issue — VoiceOver, Dynamic Type, color contrast, touch targets, WCAG compliance, App Store accessibility review.
Use when implementing, testing, or evaluating ANY Apple Intelligence, on-device AI, or speech-to-text feature. Covers Foundation Models, @Generable,…
Use when the user has a crash log (.ips, MetricKit JSON, legacy .crash text, .xccrashpoint bundle, or pasted text) that needs analysis.
Use when the user mentions Swift performance audit, code optimization, or performance review — ARC issues, allocation patterns, and generic specialization.
Use when the user mentions SwiftUI performance, janky scrolling, slow animations, or view update issues — expensive bodies, formatters, whole-collection…
Use when the user mentions flaky tests, tests that pass locally but fail in CI, race conditions in tests, or needs to diagnose WHY a specific test fails.