fix: v0.5.5 — parser brace-counting, implicit relations, FK ordering - #63
Conversation
3 critical bugs fixed:
1. Parser: inline comments with { or } truncated model body extraction.
Replaced [^}]+ regex with brace-counting _extractBlocks() for both
model and enum parsing. (Waitlist was missing userId/webinarId/classId)
2. Parser: implicit relations (fields whose type is a model name but
without @relation attribute) were not detected. Domain's subDomains,
tags, consultantProfiles were parsed as non-relation fields.
3. Schema registry: wrong FK when a model has multiple relations to the
same target (ModerationReport→User). Now uses field's own
@relation(fields:[...]) before falling back to convention lookup.
Integration-tested with familiarise_mobile dart_frog backend.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
There was a problem hiding this comment.
Code Review
This pull request updates the Prisma Flutter Connector to version 0.5.5, introducing fixes for model parsing, implicit relation detection, and foreign key resolution in multi-relation models. The parser now uses a brace-counting method to extract blocks, and relation detection has been expanded to include fields referencing known models. Review feedback suggests improving the brace-counting logic to skip comments to avoid issues with unbalanced braces, restructuring the foreign key resolution to avoid unreachable code paths, and removing redundant string operations in the parser.
| while (i < content.length && depth > 0) { | ||
| final ch = content[i]; | ||
| if (ch == '{') depth++; | ||
| if (ch == '}') depth--; | ||
| i++; | ||
| } | ||
| // i is now past the closing }, body is between start and i-1 | ||
| blocks.add(_Block(name: name, body: content.substring(start, i - 1))); |
There was a problem hiding this comment.
The brace-counting logic is still susceptible to the same truncation issue if a comment contains an unbalanced closing brace (e.g., // }). Since the primary goal of this PR is to handle braces in comments, the extraction loop should explicitly skip characters within comments while tracking the block depth. Additionally, it's safer to verify that the block was correctly closed (depth == 0) before adding it to the list.
while (i < content.length && depth > 0) {
final ch = content[i];
// Skip inline comments to avoid false depth triggers from braces in comments
if (ch == '/' && i + 1 < content.length && content[i + 1] == '/') {
while (i < content.length && content[i] != '\n') i++;
continue;
}
if (ch == '{') depth++;
if (ch == '}') depth--;
i++;
}
if (depth == 0) {
blocks.add(_Block(name: name, body: content.substring(start, i - 1)));
}| final fk = _findForeignKeyFromField(field) ?? | ||
| _findForeignKeyOnModel(model, target); |
There was a problem hiding this comment.
The call to _findForeignKeyOnModel is currently unreachable because _findForeignKeyFromField always returns a non-null string (it falls back to a default convention if no explicit relation is found). This logic should be restructured to prioritize explicit relations on the field, then check for explicit relations elsewhere in the model, and finally fall back to the naming convention.
final fk = (field.relationFromFields?.isNotEmpty == true)
? field.relationFromFields!.first
: (_findForeignKeyOnModel(model, target) ??
'${toLowerCamelCase(field.type)}Id');| final baseFieldType = | ||
| fieldType.replaceAll('?', '').replaceAll('[]', ''); |
Summary
Fixes 3 critical parser/generator bugs found during schema verification.
Bug 1: Inline comments with
{/}truncate model parsingpreferences Json? // e.g., { preferredDates: [], maxPrice: 500 }— the}in the comment closed the regex match[^}]+regex with brace-counting_extractBlocks()for both model and enum parsinguserId,webinarId,classIdfieldsBug 2: Implicit relations not detected
subDomains SubDomain[](no@relationattribute) were parsed as non-relation fieldsfieldTypeis a known model name in addition to@relationBug 3: Wrong FK for multi-relation models
reportedBy→UserandtargetUser→User. Generator picked first match's FK for both.@relation(fields:[...])before convention-based lookuptargetUserFK wasreportedByIdinstead oftargetUserIdTest plan
flutter analyze --fatal-infos— zero issuesdart format --set-exit-if-changed .— zero changes🤖 Generated with Claude Code