Skip to content

Auth#1

Merged
emma31-dev merged 8 commits into
masterfrom
auth
May 21, 2026
Merged

Auth#1
emma31-dev merged 8 commits into
masterfrom
auth

Conversation

@emma31-dev
Copy link
Copy Markdown
Owner

No description provided.

@qodo-code-review
Copy link
Copy Markdown

Review Summary by Qodo

Refine initial database schema and migrations

✨ Enhancement

Grey Divider

Walkthroughs

Description
• Refined database schema with improved comments and structure
• Made public_key optional for future E2EE implementation
• Added soft delete support to messages table
• Cleaned up migration file with clearer table documentation
Diagram
flowchart LR
  users["users table<br/>with optional public_key"]
  chats["chats table<br/>for conversations"]
  participants["chat_participants<br/>many-to-many"]
  messages["messages table<br/>with soft delete"]
  indexes["performance indexes"]
  
  users -- "references" --> participants
  chats -- "references" --> participants
  chats -- "references" --> messages
  users -- "references" --> messages
  messages -- "indexed by" --> indexes

Loading

File Changes

1. migrations/20250521102510_initial_schema.sql ✨ Enhancement +0/-0

Refactor schema with optional fields and soft deletes

• Simplified inline comments for better readability
• Changed public_key from NOT NULL to nullable for future E2EE support
• Added deleted_at column to messages table for soft delete functionality
• Improved table and section documentation with clearer naming
• Removed one redundant index on chat_participants

migrations/20250521102510_initial_schema.sql


2. migrations/20260521102510_initial_schema.sql Additional files +16/-15

...

migrations/20260521102510_initial_schema.sql


Grey Divider

Qodo Logo

@qodo-code-review
Copy link
Copy Markdown

qodo-code-review Bot commented May 21, 2026

Code Review by Qodo

🐞 Bugs (1) 📘 Rule violations (0) 📎 Requirement gaps (0)

Grey Divider


Action required

1. Migration path mismatch ✓ Resolved 🐞 Bug ☼ Reliability
Description
The migration is added under migrations/, but the app runs sqlx::migrate! from ./schemas/, so
this migration will not be applied during startup. As a result, tables like users may not exist
when routes execute SQL against them.
Code

migrations/20260521102510_initial_schema.sql[R1-10]

Evidence
The migration file in this PR lives under migrations/, but run_migrations() is configured to
load migrations from ./schemas/ and is invoked at application startup; additionally, the signup
route issues an insert into users, which requires the migration to have been applied.

src/db/mod.rs[11-13]
src/main.rs[10-15]
src/routes/signup.rs[48-57]
migrations/20260521102510_initial_schema.sql[1-43]

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 application runs migrations from `./schemas/`, but this PR adds the schema migration under `migrations/`. With the current configuration, this migration will not be executed.

### Issue Context
`main` runs `run_migrations()` at startup, and routes (e.g., signup) execute SQL against `users`.

### Fix Focus Areas
- src/db/mod.rs[11-13]
- src/main.rs[10-15]
- migrations/20260521102510_initial_schema.sql[1-43]

### Suggested fix
Make the migration directory consistent by doing one of:
- Change `sqlx::migrate!("./schemas/")` to `sqlx::migrate!("./migrations")`, OR
- Move the migration file(s) into the `schemas/` directory (and ensure they’re named per sqlx expectations).

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


2. Invalid FK delete action 🐞 Bug ≡ Correctness
Description
messages.sender_id is declared NOT NULL but uses ON DELETE SET NULL, so deleting a referenced
users row will fail with a constraint error when foreign keys are enforced. This makes user
hard-deletes unreliable and the FK action effectively incorrect.
Code

migrations/20260521102510_initial_schema.sql[31]

Evidence
The migration defines sender_id as NOT NULL while also specifying ON DELETE SET NULL, and the
app explicitly enables SQLite foreign key enforcement, making this contradiction a runtime error on
delete.

migrations/20260521102510_initial_schema.sql[28-37]
src/db/mod.rs[4-8]

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

### Issue description
`messages.sender_id` is `NOT NULL` while the FK specifies `ON DELETE SET NULL`. SQLite will attempt to set `sender_id` to NULL on user deletion, which violates `NOT NULL` and aborts the delete.

### Issue Context
Foreign key enforcement is enabled in the application’s SQLite connection options, so this will surface as a runtime failure.

### Fix Focus Areas
- migrations/20260521102510_initial_schema.sql[28-37]
- src/db/mod.rs[4-8]

### Suggested fix
Pick one consistent behavior:
- If you want to preserve messages when a user is deleted: make `sender_id` nullable (remove `NOT NULL`) and keep `ON DELETE SET NULL`.
- If you never want user deletion to orphan messages: keep `NOT NULL` and change the FK action to `ON DELETE RESTRICT`/`NO ACTION` (or `CASCADE` if appropriate).

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


Grey Divider

Qodo Logo

nonce BLOB NOT NULL, -- 12 bytes unique per message
tag BLOB NOT NULL, -- 16 bytes authentication tag
created_at TEXT NOT NULL DEFAULT (datetime('now'))
sender_id TEXT NOT NULL REFERENCES users(id) ON DELETE SET NULL,
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Action required

1. Invalid fk delete action 🐞 Bug ≡ Correctness

messages.sender_id is declared NOT NULL but uses ON DELETE SET NULL, so deleting a referenced
users row will fail with a constraint error when foreign keys are enforced. This makes user
hard-deletes unreliable and the FK action effectively incorrect.
Agent Prompt
### Issue description
`messages.sender_id` is `NOT NULL` while the FK specifies `ON DELETE SET NULL`. SQLite will attempt to set `sender_id` to NULL on user deletion, which violates `NOT NULL` and aborts the delete.

### Issue Context
Foreign key enforcement is enabled in the application’s SQLite connection options, so this will surface as a runtime failure.

### Fix Focus Areas
- migrations/20260521102510_initial_schema.sql[28-37]
- src/db/mod.rs[4-8]

### Suggested fix
Pick one consistent behavior:
- If you want to preserve messages when a user is deleted: make `sender_id` nullable (remove `NOT NULL`) and keep `ON DELETE SET NULL`.
- If you never want user deletion to orphan messages: keep `NOT NULL` and change the FK action to `ON DELETE RESTRICT`/`NO ACTION` (or `CASCADE` if appropriate).

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

Comment thread migrations/20260521102510_initial_schema.sql
@qodo-code-review
Copy link
Copy Markdown

CI Feedback 🧐

A test triggered by this PR failed. Here is an AI-generated analysis of the failure:

Action: build

Failed stage: Checking [❌]

Failed test name: ""

Failure summary:

The action failed during compilation because sqlx::query! requires either:
- a DATABASE_URL
environment variable to connect and validate queries at build time (online mode), or
- an up-to-date
SQLx offline cache generated by running cargo sqlx prepare.

The compiler error occurred at src/routes/login.rs:27:15 where sqlx::query! is used, and the build
aborted with exit code 101 (could not compile encrypted-message-sender).

Relevant error logs:
1:  ##[group]Runner Image Provisioner
2:  Hosted Compute Agent
...

121:  shell: /usr/bin/bash -e {0}
122:  env:
123:  CARGO_TERM_COLOR: always
124:  ##[endgroup]
125:  �[1m�[92m    Updating�[0m crates.io index
126:  �[1m�[92m Downloading�[0m crates ...
127:  �[1m�[92m  Downloaded�[0m bcrypt v0.19.1
128:  �[1m�[92m  Downloaded�[0m aead v0.5.2
129:  �[1m�[92m  Downloaded�[0m aes v0.8.4
130:  �[1m�[92m  Downloaded�[0m openssl-probe v0.2.1
131:  �[1m�[92m  Downloaded�[0m num-iter v0.1.45
132:  �[1m�[92m  Downloaded�[0m polyval v0.6.2
133:  �[1m�[92m  Downloaded�[0m tracing-serde v0.2.0
134:  �[1m�[92m  Downloaded�[0m time-core v0.1.8
135:  �[1m�[92m  Downloaded�[0m sqlx-macros-core v0.8.6
136:  �[1m�[92m  Downloaded�[0m thiserror-impl v2.0.18
137:  �[1m�[92m  Downloaded�[0m pkcs1 v0.7.5
...

192:  �[1m�[92m  Downloaded�[0m num-bigint v0.4.6
193:  �[1m�[92m  Downloaded�[0m http v0.2.12
194:  �[1m�[92m  Downloaded�[0m pkcs8 v0.10.2
195:  �[1m�[92m  Downloaded�[0m num-integer v0.1.46
196:  �[1m�[92m  Downloaded�[0m simple_asn1 v0.6.4
197:  �[1m�[92m  Downloaded�[0m quote v1.0.45
198:  �[1m�[92m  Downloaded�[0m matchers v0.2.0
199:  �[1m�[92m  Downloaded�[0m sqlx-macros v0.8.6
200:  �[1m�[92m  Downloaded�[0m slab v0.4.12
201:  �[1m�[92m  Downloaded�[0m rand_chacha v0.3.1
202:  �[1m�[92m  Downloaded�[0m proc-macro2 v1.0.106
203:  �[1m�[92m  Downloaded�[0m mio v1.2.0
204:  �[1m�[92m  Downloaded�[0m md-5 v0.10.6
205:  �[1m�[92m  Downloaded�[0m zerovec v0.11.6
206:  �[1m�[92m  Downloaded�[0m signal-hook-registry v1.4.8
207:  �[1m�[92m  Downloaded�[0m serde_path_to_error v0.1.20
208:  �[1m�[92m  Downloaded�[0m serde_json v1.0.149
209:  �[1m�[92m  Downloaded�[0m pin-project-internal v1.1.13
210:  �[1m�[92m  Downloaded�[0m num-conv v0.2.2
211:  �[1m�[92m  Downloaded�[0m unicode-ident v1.0.24
212:  �[1m�[92m  Downloaded�[0m thiserror v2.0.18
213:  �[1m�[92m  Downloaded�[0m symlink v0.1.0
...

382:  �[1m�[92m   Compiling�[0m crossbeam-utils v0.8.21
383:  �[1m�[92m   Compiling�[0m stable_deref_trait v1.2.1
384:  �[1m�[92m   Compiling�[0m icu_properties_data v2.2.0
385:  �[1m�[92m    Checking�[0m smallvec v1.15.1
386:  �[1m�[92m   Compiling�[0m zmij v1.0.21
387:  �[1m�[92m    Checking�[0m pin-project-lite v0.2.17
388:  �[1m�[92m    Checking�[0m itoa v1.0.18
389:  �[1m�[92m   Compiling�[0m openssl-sys v0.9.116
390:  �[1m�[92m    Checking�[0m getrandom v0.2.17
391:  �[1m�[92m    Checking�[0m rand_core v0.6.4
392:  �[1m�[92m   Compiling�[0m serde_json v1.0.149
393:  �[1m�[92m    Checking�[0m crypto-common v0.1.7
394:  �[1m�[92m    Checking�[0m scopeguard v1.2.0
395:  �[1m�[92m    Checking�[0m futures-core v0.3.32
396:  �[1m�[92m    Checking�[0m memchr v2.8.0
397:  �[1m�[92m   Compiling�[0m thiserror v2.0.18
398:  �[1m�[92m    Checking�[0m lock_api v0.4.14
...

410:  �[1m�[92m   Compiling�[0m native-tls v0.2.18
411:  �[1m�[92m    Checking�[0m parking_lot v0.12.5
412:  �[1m�[92m    Checking�[0m errno v0.3.14
413:  �[1m�[92m    Checking�[0m futures-io v0.3.32
414:  �[1m�[92m    Checking�[0m slab v0.4.12
415:  �[1m�[92m   Compiling�[0m zerofrom-derive v0.1.7
416:  �[1m�[92m   Compiling�[0m yoke-derive v0.8.2
417:  �[1m�[92m   Compiling�[0m zerovec-derive v0.11.3
418:  �[1m�[92m   Compiling�[0m displaydoc v0.2.5
419:  �[1m�[92m   Compiling�[0m serde_derive v1.0.228
420:  �[1m�[92m   Compiling�[0m zerofrom v0.1.8
421:  �[1m�[92m   Compiling�[0m yoke v0.8.2
422:  �[1m�[92m   Compiling�[0m zerovec v0.11.6
423:  �[1m�[92m   Compiling�[0m tracing-attributes v0.1.31
424:  �[1m�[92m   Compiling�[0m tinystr v0.8.3
425:  �[1m�[92m   Compiling�[0m thiserror-impl v2.0.18
426:  �[1m�[92m   Compiling�[0m icu_locale_core v2.2.0
...

540:  �[1m�[92m    Checking�[0m untrusted v0.7.1
541:  �[1m�[92m    Checking�[0m httpdate v1.0.3
542:  �[1m�[92m    Checking�[0m nu-ansi-term v0.50.3
543:  �[1m�[92m    Checking�[0m mime v0.3.17
544:  �[1m�[92m    Checking�[0m hyper v0.14.32
545:  �[1m�[92m    Checking�[0m tracing-subscriber v0.3.23
546:  �[1m�[92m    Checking�[0m blowfish v0.10.0
547:  �[1m�[92m    Checking�[0m simple_asn1 v0.6.4
548:  �[1m�[92m   Compiling�[0m sqlx-macros v0.8.6
549:  �[1m�[92m    Checking�[0m ghash v0.5.1
550:  �[1m�[92m    Checking�[0m tower v0.4.13
551:  �[1m�[92m    Checking�[0m aes v0.8.4
552:  �[1m�[92m    Checking�[0m ctr v0.9.2
553:  �[1m�[92m    Checking�[0m pem v3.0.6
554:  �[1m�[92m    Checking�[0m crossbeam-channel v0.5.15
555:  �[1m�[92m    Checking�[0m serde_path_to_error v0.1.20
556:  �[1m�[92m    Checking�[0m aead v0.5.2
557:  �[1m�[92m    Checking�[0m bitflags v1.3.2
558:  �[1m�[92m    Checking�[0m sync_wrapper v0.1.2
559:  �[1m�[92m    Checking�[0m signature v2.2.0
560:  �[1m�[92m    Checking�[0m matchit v0.7.3
561:  �[1m�[92m    Checking�[0m symlink v0.1.0
562:  �[1m�[92m    Checking�[0m aes-gcm v0.10.3
563:  �[1m�[92m    Checking�[0m tracing-appender v0.2.5
564:  �[1m�[92m    Checking�[0m sqlx v0.8.6
565:  �[1m�[92m    Checking�[0m bcrypt v0.19.1
566:  �[1m�[92m    Checking�[0m jsonwebtoken v10.4.0
567:  �[1m�[92m    Checking�[0m encrypted-message-sender v0.1.0 (/home/runner/work/encrypted-message-sender/encrypted-message-sender)
568:  �[1m�[91merror�[0m�[1m: set `DATABASE_URL` to use query macros online, or run `cargo sqlx prepare` to update the query cache�[0m
569:  �[1m�[94m--> �[0msrc/routes/login.rs:27:15
570:  �[1m�[94m|�[0m
571:  �[1m�[94m27�[0m �[1m�[94m|�[0m       let row = sqlx::query!(
572:  �[1m�[94m|�[0m �[1m�[91m _______________^�[0m
573:  �[1m�[94m28�[0m �[1m�[94m|�[0m �[1m�[91m|�[0m         "SELECT id, password_hash FROM users WHERE username = ? AND deleted_at IS NULL",
574:  �[1m�[94m29�[0m �[1m�[94m|�[0m �[1m�[91m|�[0m         payload.username
575:  �[1m�[94m30�[0m �[1m�[94m|�[0m �[1m�[91m|�[0m     )
576:  �[1m�[94m|�[0m �[1m�[91m|_____^�[0m
577:  �[1m�[94m|�[0m
578:  �[1m�[94m= �[0m�[1mnote�[0m: this error originates in the macro `$crate::sqlx_macros::expand_query` which comes from the expansion of the macro `sqlx::query` (in Nightly builds, run with -Z macro-backtrace for more info)
579:  �[1m�[91merror�[0m: could not compile `encrypted-message-sender` (lib) due to 1 previous error
580:  ##[error]Process completed with exit code 101.
581:  Post job cleanup.

@emma31-dev emma31-dev merged commit 0213fd3 into master May 21, 2026
1 check failed
@emma31-dev emma31-dev deleted the auth branch May 21, 2026 21:38
@emma31-dev emma31-dev restored the auth branch May 22, 2026 08:11
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.

1 participant