Skip to content

Conversation

@jjmata
Copy link
Collaborator

@jjmata jjmata commented Jan 12, 2026

  • Add AppConfig class with product_name and brand_name following Rails pattern (configurable via --dart-define at build time)
  • Create design system (SureColors, SureBorderRadius, SureShadows, SureTypography) matching the Rails/Tailwind design tokens
  • Add SureTheme builder for light/dark themes using design system
  • Update main.dart to use AppConfig and SureTheme
  • Update example URLs to use app.sure.am

Summary by CodeRabbit

  • New Features

    • Configurable branding for the mobile app (product/brand can be set at build time)
    • Comprehensive design system and new light/dark themes for consistent visuals
  • Chores

    • App version updated to 0.6.7-alpha.8
    • Updated example/backend URL shown in the app
    • Refactored theme implementation for improved consistency and reuse

✏️ Tip: You can customize this high-level summary in your review settings.

- Add AppConfig class with product_name and brand_name following
  Rails pattern (configurable via --dart-define at build time)
- Create design system (SureColors, SureBorderRadius, SureShadows,
  SureTypography) matching the Rails/Tailwind design tokens
- Add SureTheme builder for light/dark themes using design system
- Update main.dart to use AppConfig and SureTheme
- Update example URLs to use app.sure.am
@coderabbitai
Copy link

coderabbitai bot commented Jan 12, 2026

📝 Walkthrough

Walkthrough

Centralizes version reading via a repository VERSION file and adds a Ruby sync script. Introduces a compile-time AppConfig, a full Flutter design system (SureColors, typography, radii, shadows) and a SureTheme builder; main.dart and Rails initializer now read the shared version or environment values.

Changes

Cohort / File(s) Summary
Version management
\VERSION`, `bin/sync-mobile-version`, `config/initializers/version.rb`, `mobile/pubspec.yaml``
Added VERSION containing 0.6.7-alpha.8. New Ruby script bin/sync-mobile-version reads VERSION, derives a Flutter-formatted version, compares/updates mobile/pubspec.yaml (supports --check). Rails initializer now reads version from VERSION with a fallback. mobile/pubspec.yaml bumped to 0.6.7-alpha.8+8.
Mobile configuration & text
\mobile/lib/config/app_config.dart`, `mobile/lib/screens/backend_config_screen.dart``
Added AppConfig with compile-time PRODUCT_NAME/BRAND_NAME and derived appTitle/copyrightNotice. Updated displayed backend URL examples/placeholders to https://app.sure.am.
Design system & theming
\mobile/lib/theme/design_system.dart`, `mobile/lib/theme/sure_theme.dart`, `mobile/lib/main.dart``
New design system (SureColors, SureTypography, SureBorderRadius, SureShadows) with light/dark semantic helpers. New SureTheme with light()/dark() ThemeData builders. main.dart updated to use AppConfig and SureTheme (removed previous inline ThemeData).

Sequence Diagram(s)

(omitted)

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Poem

🐰 A VERSION hop, a tiny scroll,
Colors gathered, fonts in role—
Themes stitched tidy, configs sing,
Syncing versions, new bells ring.
Carrots and code, I bound and stroll. 🥕✨

🚥 Pre-merge checks | ✅ 1 | ❌ 2
❌ Failed checks (1 warning, 1 inconclusive)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
Title check ❓ Inconclusive The title 'Align mobile Flutter branding with PWA (if possible)' is partially related to the changeset. The PR does align mobile branding through AppConfig, design system, and theming, but the 'with PWA' portion and '(if possible)' qualifier are vague and not clearly demonstrated by the changes. The focus should be on the branding alignment itself. Clarify the title by removing vague qualifiers like '(if possible)' and either explain the PWA connection or remove it. Consider: 'Add mobile branding configuration and design system' or 'Align mobile Flutter app branding and theming'.
✅ Passed checks (1 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing touches
  • 📝 Generate docstrings


📜 Recent review details

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 8786a46 and b2b88d9.

📒 Files selected for processing (1)
  • config/initializers/version.rb
🚧 Files skipped from review as they are similar to previous changes (1)
  • config/initializers/version.rb
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (3)
  • GitHub Check: ci / test
  • GitHub Check: Build iOS IPA
  • GitHub Check: Build Android APK

✏️ Tip: You can disable this entire section by setting review_details to false in your review settings.


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@jjmata
Copy link
Collaborator Author

jjmata commented Jan 12, 2026

/cc @dwvwdv FYI

- Add shared VERSION file (0.6.7-alpha.8) at repo root
- Update Rails version.rb to read from VERSION file
- Update Flutter pubspec.yaml to match (0.6.7-alpha.8+8)
- Add bin/sync-mobile-version script to sync versions

The sync script can be run before Flutter builds or in CI:
  bin/sync-mobile-version         # Update pubspec.yaml
  bin/sync-mobile-version --check # Verify versions match
static String get appTitle => '$productName Finance';

/// Copyright notice with brand name.
static String get copyrightNotice => '\u00A9 ${DateTime.now().year} $brandName';
Copy link

Choose a reason for hiding this comment

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

Where should this content be displayed? Perhaps it would be more appropriate to place it at the bottom of the "Settings" page?

@dwvwdv
Copy link

dwvwdv commented Jan 13, 2026

/cc @dwvwdv FYI

look goods.
I ran this version of the APK, and it performed well overall.

You could also add a theme switching menu to the settings page for easier addition of themes in the future.
However, I think the current code is sufficient, and this feature could be considered for inclusion in a future update.

@jjmata jjmata self-assigned this Jan 13, 2026
@jjmata jjmata added this to the v0.6.7 milestone Jan 13, 2026
Signed-off-by: Juan José Mata <juanjo.mata@gmail.com>
@jjmata jjmata marked this pull request as ready for review January 15, 2026 11:57
@dosubot
Copy link

dosubot bot commented Jan 15, 2026

Related Documentation

Checked 1 published document(s) in 1 knowledge base(s). No updates required.

How did I do? Any feedback?  Join Discord

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Fix all issues with AI agents
In `@config/initializers/version.rb`:
- Around line 17-23: The fallback version string currently returns
"0.6.7-alpha.9" when version_file (the Rails.root.join("VERSION") read block) is
missing; change that fallback to match or predate the actual VERSION file value
(e.g., "0.6.7-alpha.8") so the app never reports a newer release than exists, or
if the higher fallback is intentional, add a brief comment above the conditional
explaining why the fallback is intentionally newer for development/testing.
🧹 Nitpick comments (1)
mobile/lib/theme/sure_theme.dart (1)

289-383: SureTypography.fontFamilySans is not applied to the text theme.

The design system defines Geist as the primary font family in SureTypography, but _buildTextTheme doesn't set fontFamily on any TextStyle. This means the app will use the default system font instead of Geist.

♻️ Suggested fix
  static TextTheme _buildTextTheme(Brightness brightness) {
    final Color primaryTextColor =
        brightness == Brightness.dark ? SureColors.white : SureColors.gray900;
    final Color secondaryTextColor = brightness == Brightness.dark
        ? SureColors.gray300
        : SureColors.gray500;

    return TextTheme(
      displayLarge: TextStyle(
        fontSize: 57,
        fontWeight: FontWeight.w400,
        color: primaryTextColor,
        letterSpacing: -0.25,
+       fontFamily: SureTypography.fontFamilySans,
+       fontFamilyFallback: SureTypography.fontFamilySansFallback,
      ),
      // ... apply to other text styles

Alternatively, apply the font family at the ThemeData level:

return ThemeData(
  fontFamily: SureTypography.fontFamilySans,
  fontFamilyFallback: SureTypography.fontFamilySansFallback,
  // ...
);

Ensure the Geist font assets are bundled in pubspec.yaml under the fonts section for this to work.

📜 Review details

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between fabd60c and 8786a46.

📒 Files selected for processing (9)
  • VERSION
  • bin/sync-mobile-version
  • config/initializers/version.rb
  • mobile/lib/config/app_config.dart
  • mobile/lib/main.dart
  • mobile/lib/screens/backend_config_screen.dart
  • mobile/lib/theme/design_system.dart
  • mobile/lib/theme/sure_theme.dart
  • mobile/pubspec.yaml
🧰 Additional context used
📓 Path-based instructions (6)
**/*.rb

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

**/*.rb: Application supports two modes: 'managed' and 'self_hosted' via Rails.application.config.app_mode
Use Current.user and Current.family instead of current_user / current_family for authentication context
Optimize database queries with proper indexes to prevent N+1 queries using includes/joins

**/*.rb: Use 2-space indentation for Ruby code
Use snake_case for method and variable names in Ruby
Use CamelCase for class and module names in Ruby
Run bin/rubocop before pushing code; use -A flag to auto-correct safe style violations

**/*.rb: Use Current.user for the current user. Do NOT use current_user.
Use Current.family for the current family. Do NOT use current_family.

Files:

  • config/initializers/version.rb
**/*.{rb,erb}

📄 CodeRabbit inference engine (.cursor/rules/general-rules.mdc)

**/*.{rb,erb}: Use Current.user for accessing the current user. Do NOT use current_user
Use Current.family for accessing the current family. Do NOT use current_family

Files:

  • config/initializers/version.rb
**/*.{rb,js,erb}

📄 CodeRabbit inference engine (.cursor/rules/project-conventions.mdc)

Format currencies, numbers, dates, and other values server-side, then pass to Stimulus controllers for display only

Files:

  • config/initializers/version.rb
**/*.{rb,html.erb}

📄 CodeRabbit inference engine (.cursor/rules/project-conventions.mdc)

Use ActiveRecord validations for complex validations and business logic. Simple validations may be mirrored in ActiveRecord for form error handling convenience, but prioritize client-side form validation when possible

Files:

  • config/initializers/version.rb
config/**

📄 CodeRabbit inference engine (AGENTS.md)

Place configuration files in config/ directory

Files:

  • config/initializers/version.rb
**/*.{erb,rb}

📄 CodeRabbit inference engine (CLAUDE.md)

**/*.{erb,rb}: All user-facing strings must use localization (i18n). Always use t() helper. Update locale files for each new or changed element.
Use i18n interpolation for dynamic content: t("users.greeting", name: user.name)
Use Rails pluralization in i18n: t("transactions.count", count: @transactions.count)

Files:

  • config/initializers/version.rb
🧠 Learnings (11)
📓 Common learnings
Learnt from: CR
Repo: we-promise/sure PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-01-10T19:11:44.566Z
Learning: Applies to **/*.{erb,js,ts,tsx} : Use functional tokens defined in design system (e.g., `text-primary` instead of `text-white`, `bg-container` instead of `bg-white`)
📚 Learning: 2026-01-02T09:16:53.865Z
Learnt from: dwvwdv
Repo: we-promise/sure PR: 426
File: mobile/lib/providers/accounts_provider.dart:97-103
Timestamp: 2026-01-02T09:16:53.865Z
Learning: In the Flutter mobile app (mobile/ directory), the maintainer prefers keeping error messages simple and user-friendly rather than exposing detailed technical error information, even when catching generic exceptions in provider classes.

Applied to files:

  • mobile/lib/main.dart
📚 Learning: 2026-01-09T12:25:59.839Z
Learnt from: jjmata
Repo: we-promise/sure PR: 593
File: app/controllers/pages_controller.rb:200-203
Timestamp: 2026-01-09T12:25:59.839Z
Learning: Do not compare hard-coded strings to identify the 'Uncategorized Investments' category in Ruby/Rails code (e.g., ct.category.name != "Uncategorized Investments"). Localization/internationalization can change strings. Prefer: (1) a model-level predicate such as ct.category.uncategorized_investment? or (2) compare by identity with a canonical category, e.g., ct.category != Category.uncategorized_investments. This improves maintainability and correctness across translations. Apply this pattern to Ruby files that perform category checks (controllers, models, or elsewhere).

Applied to files:

  • config/initializers/version.rb
📚 Learning: 2026-01-10T19:11:44.566Z
Learnt from: CR
Repo: we-promise/sure PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-01-10T19:11:44.566Z
Learning: Applies to **/*.{erb,js,ts,tsx} : Use functional tokens defined in design system (e.g., `text-primary` instead of `text-white`, `bg-container` instead of `bg-white`)

Applied to files:

  • mobile/lib/theme/design_system.dart
📚 Learning: 2025-11-24T16:57:09.166Z
Learnt from: CR
Repo: we-promise/sure PR: 0
File: .cursor/rules/ui-ux-design-guidelines.mdc:0-0
Timestamp: 2025-11-24T16:57:09.166Z
Learning: Applies to {app/views/**,app/helpers/**,app/javascript/controllers/**} : Prefer using functional design system tokens (e.g., text-primary, bg-container, border-primary) from maybe-design-system.css instead of raw Tailwind color values

Applied to files:

  • mobile/lib/theme/design_system.dart
📚 Learning: 2025-11-24T16:54:59.198Z
Learnt from: CR
Repo: we-promise/sure PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-11-24T16:54:59.198Z
Learning: Always reference app/assets/tailwind/maybe-design-system.css for design system tokens and primitives

Applied to files:

  • mobile/lib/theme/design_system.dart
📚 Learning: 2025-08-22T18:30:26.758Z
Learnt from: jjmata
Repo: we-promise/sure PR: 116
File: app/views/family_exports/_list.html.erb:16-28
Timestamp: 2025-08-22T18:30:26.758Z
Learning: In the family exports UI (app/views/family_exports/_list.html.erb), raw color utilities like bg-green-500/5, text-green-500, bg-red-500/5, text-red-500 are preferred over design system tokens for status indicators to maintain UI legibility and consistency with the existing import UI patterns. The user has indicated that design token replacements would make the UI illegible in this context.

Applied to files:

  • mobile/lib/theme/design_system.dart
📚 Learning: 2026-01-10T19:11:44.566Z
Learnt from: CR
Repo: we-promise/sure PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-01-10T19:11:44.566Z
Learning: Applies to app/assets/tailwind/maybe-design-system.css : NEVER create new styles in design system files without permission

Applied to files:

  • mobile/lib/theme/design_system.dart
📚 Learning: 2025-11-24T16:54:59.198Z
Learnt from: CR
Repo: we-promise/sure PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-11-24T16:54:59.198Z
Learning: Applies to app/views/**/*.erb : Use Tailwind design tokens (e.g., text-primary, bg-container, border-secondary) instead of raw color names

Applied to files:

  • mobile/lib/theme/design_system.dart
📚 Learning: 2026-01-10T19:11:44.566Z
Learnt from: CR
Repo: we-promise/sure PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-01-10T19:11:44.566Z
Learning: Applies to **/*.{erb,js,ts,tsx} : In TailwindCSS, always reference `app/assets/tailwind/maybe-design-system.css` for primitives and tokens

Applied to files:

  • mobile/lib/theme/design_system.dart
📚 Learning: 2025-11-24T16:57:09.166Z
Learnt from: CR
Repo: we-promise/sure PR: 0
File: .cursor/rules/ui-ux-design-guidelines.mdc:0-0
Timestamp: 2025-11-24T16:57:09.166Z
Learning: Applies to {app/views/**,app/helpers/**,app/javascript/controllers/**} : Reference maybe-design-system.css for base primitives, functional tokens, and component tokens before writing styles

Applied to files:

  • mobile/lib/theme/design_system.dart
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (3)
  • GitHub Check: ci / test
  • GitHub Check: Build Android APK
  • GitHub Check: Build iOS IPA
🔇 Additional comments (13)
VERSION (1)

1-1: LGTM!

Single source of truth for versioning across the monorepo. The format aligns with semver expectations in the consuming scripts (config/initializers/version.rb and bin/sync-mobile-version).

mobile/pubspec.yaml (1)

4-4: LGTM!

Version correctly aligned with the monorepo VERSION file (0.6.7-alpha.8) using Flutter's format with build number derived from the prerelease suffix.

mobile/lib/screens/backend_config_screen.dart (1)

228-228: LGTM!

Consistent URL branding update to https://app.sure.am in both the example list and hint text.

Also applies to: 321-321

bin/sync-mobile-version (1)

1-102: LGTM!

Well-structured synchronization script with:

  • Clear usage documentation
  • Proper error handling with informative messages
  • CI-friendly --check mode with appropriate exit codes
  • Correct semver parsing and Flutter version format conversion
mobile/lib/theme/design_system.dart (3)

193-305: Well-structured semantic color system.

The context-aware color helpers properly map light/dark mode variants and align with the functional token pattern from the Rails design system. The use of withValues(alpha:) is the correct modern Flutter API.


314-420: LGTM!

Typography, border radius, and shadow utilities are well-implemented with proper font fallbacks and context-aware shadow colors for light/dark mode.


98-99: Design system bug in Rails: cyan-800 and cyan-900 are identical.

The duplicate 0xFF155B75 in cyan800 and cyan900 exists in both the Flutter code AND the authoritative Rails design system (app/assets/tailwind/maybe-design-system.css). This is the only color scale with this issue—all other scales (blue, fuchsia, gray, green, indigo, orange, pink, red, yellow) have properly distinct 800 and 900 values.

The Flutter implementation is correct. The bug is in the Rails design system file, which should be fixed first; then the Flutter values can be updated to match.

Likely an incorrect or invalid review comment.

mobile/lib/theme/sure_theme.dart (2)

14-149: Comprehensive light theme configuration.

The theme properly uses design system tokens for all component themes, ensuring visual consistency with the Rails/Tailwind design system. Good use of ColorScheme.fromSeed with explicit overrides.


151-287: Dark theme mirrors light theme structure correctly.

Proper dark mode color mappings using the appropriate design system tokens (e.g., gray900 for surfaces, gray700 for borders).

mobile/lib/main.dart (3)

3-3: Clean import additions for config and theme.

The new imports properly integrate the AppConfig and SureTheme modules.

Also applies to: 14-14


21-21: Dynamic product name in startup log.

The log message now uses AppConfig.productName, supporting compile-time branding customization.


65-69: MaterialApp properly configured with new theme and config.

The app title and themes are now sourced from centralized configuration, enabling consistent branding across builds.

mobile/lib/config/app_config.dart (1)

14-36: Well-designed compile-time configuration class.

The use of String.fromEnvironment with defaults correctly mirrors the Rails pattern and enables build-time customization via --dart-define. The private constructor appropriately prevents instantiation of this utility class.

✏️ Tip: You can disable this entire section by setting review_details to false in your review settings.

Comment on lines 17 to 23
# Read from shared VERSION file at repo root
version_file = Rails.root.join("VERSION")
if version_file.exist?
version_file.read.strip
else
"0.6.7-alpha.9"
end
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Fallback version is higher than the current VERSION file value.

The VERSION file contains 0.6.7-alpha.8, but the fallback is 0.6.7-alpha.9. If the VERSION file is missing during deployment, the app would incorrectly report a newer version than the actual release.

Consider aligning the fallback to match or predate the current version:

Suggested fix
       if version_file.exist?
         version_file.read.strip
       else
-        "0.6.7-alpha.9"
+        "0.6.7-alpha.8"
       end

Alternatively, if the fallback is intentional for development purposes, add a comment explaining the rationale.

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
# Read from shared VERSION file at repo root
version_file = Rails.root.join("VERSION")
if version_file.exist?
version_file.read.strip
else
"0.6.7-alpha.9"
end
# Read from shared VERSION file at repo root
version_file = Rails.root.join("VERSION")
if version_file.exist?
version_file.read.strip
else
"0.6.7-alpha.8"
end
🤖 Prompt for AI Agents
In `@config/initializers/version.rb` around lines 17 - 23, The fallback version
string currently returns "0.6.7-alpha.9" when version_file (the
Rails.root.join("VERSION") read block) is missing; change that fallback to match
or predate the actual VERSION file value (e.g., "0.6.7-alpha.8") so the app
never reports a newer release than exists, or if the higher fallback is
intentional, add a brief comment above the conditional explaining why the
fallback is intentionally newer for development/testing.

Signed-off-by: Juan José Mata <juanjo.mata@gmail.com>
@dwvwdv
Copy link

dwvwdv commented Jan 21, 2026

@jjmata Is something missing here? Why isn't it merged?
Is there anything I can do to help?

I'm planning to adjust some styles recently, and making changes now might cause some conflicts.

@jjmata
Copy link
Collaborator Author

jjmata commented Jan 21, 2026

Nothing missing, just me wondering if these are "best practices" or not. 🤷‍♂️

What do you think? Seems a little Quixotic to try to keep uniformity of design system between PWA and Flutter, no?

Don't let this block your changes, I can always rebase mine.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

Status: No status

Development

Successfully merging this pull request may close these issues.

4 participants