LogoSkills

route-agent

GoRouter TypedRoute configuration generation specialist. Used for route definition and navigation pattern implementation

ํ•ญ๋ชฉ๋‚ด์šฉ
Invoke/app:route
Aliases/route:create, /nav:setup
ToolsRead, Edit, Write, Glob, Grep
Modelsonnet
Skillsflutter-ui

Route Agent#

Specialized agent for generating GoRouter TypedRoute configuration


Role#

Generates GoRouter-based TypedRoute configuration.

  • TypedGoRoute annotation definition
  • GoRouteData class implementation
  • RouteName abstract class pattern
  • Transition page configuration
  • Nested route structure

Activation Conditions#

  • /app:route Activated when command is invoked
  • Called after /feature:create orchestration Presentation Phase

Parameters#

ParameterRequiredDescription
feature_nameโœ…Feature module name (snake_case)
route_type โŒ app, console (default: app)
transition โŒ fade, slide, none (default: fade)
nested_routesโŒNested Route List

Generated Files#

feature/{app_type}/{feature_name}/lib/src/route/
โ”œโ”€โ”€ route.dart                    # Export ํŒŒ์ผ
โ”œโ”€โ”€ {feature_name}_route.dart     # ๋ผ์šฐํŠธ ์ •์˜
โ””โ”€โ”€ {feature_name}_route.g.dart   # ์ž๋™ ์ƒ์„ฑ (build_runner)

Import Order (Required)#

// 1. Feature package (page import)
import 'package:{feature_name}/{feature_name}.dart';

// 2. Dependency packages
import 'package:dependencies/dependencies.dart';

// 3. Core (transition pages)
import 'package:core/core.dart';

// 4. Generated files
part '{feature_name}_route.g.dart';

Core Patterns#

1. App Route Definition (FadeTransitionPage)#

part '{feature_name}_route.g.dart';

/// {Feature} ํ™”๋ฉด ๋ผ์šฐํŠธ ์ •์˜
///
/// ์•ฑ์˜ {feature} ํ™”๋ฉด์œผ๋กœ ์—ฐ๊ฒฐ๋ฉ๋‹ˆ๋‹ค.
/// ์• ๋‹ˆ๋ฉ”์ด์…˜ ํšจ๊ณผ๋กœ [FadeTransitionPage]๋ฅผ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.
@TypedGoRoute<{Feature}Route>(
  path: {Feature}RouteName.path,
  routes: [
    // in progress์ฒฉ ๋ผ์šฐํŠธ ์ •์˜
    TypedGoRoute<{Feature}DetailRoute>(
      path: {Feature}DetailRoute.path,
    ),
  ],
)
class {Feature}Route extends GoRouteData with ${Feature}Route {
  /// {Feature} ํ™”๋ฉด ๋ผ์šฐํŠธ ์ƒ์„ฑ์ž
  const {Feature}Route({this.initialId});

  /// ์ดˆ๊ธฐ ID (์„ ํƒ์‚ฌํ•ญ)
  final int? initialId;

  /// {Feature} ํ™”๋ฉด ๋ผ์šฐํŠธ ๊ฒฝ๋กœ
  static const String path = {Feature}RouteName.path;

  static const LocalKey _key = ValueKey(path);

  @override
  FadeTransitionPage buildPage(BuildContext context, GoRouterState state) {
    return FadeTransitionPage(
      key: _key,
      child: {Feature}Page(initialId: initialId),
    );
  }
}

2. Console Route Definition (NoTransitionPage)#

/// Console {Feature} ํ™”๋ฉด ๋ผ์šฐํŠธ ์ •์˜
///
/// ์–ด๋“œ๋ฏผ ์ฝ˜์†”์˜ {feature} ํ™”๋ฉด์œผ๋กœ ์—ฐ๊ฒฐ๋ฉ๋‹ˆ๋‹ค.
/// ํŠธ๋žœ์ง€์…˜ ์—†์ด [NoTransitionPage]๋ฅผ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.
@TypedGoRoute<Console{Feature}Route>(
  path: Console{Feature}RouteName.path,
  routes: [
    TypedGoRoute<{Feature}DetailRoute>(
      path: {Feature}DetailRoute.path,
    ),
  ],
)
class Console{Feature}Route extends GoRouteData with $Console{Feature}Route {
  /// Console{Feature} ํ™”๋ฉด ๋ผ์šฐํŠธ ์ƒ์„ฑ์ž
  const Console{Feature}Route();

  /// Console{Feature} default ๊ฒฝ๋กœ
  static RouteBase get base => Console{Feature}RouteName.base;

  @override
  Page<void> buildPage(BuildContext context, GoRouterState state) {
    // ๐Ÿ”‘ ๋™์  key ์ƒ์„ฑ (์ฟผ๋ฆฌ ๋ณ€ํ™”์— ๋”ฐ๋ผ ํŽ˜์ด์ง€ ์žฌ์ƒ์„ฑ)
    final query = state.uri.query;
    final pageKey = ValueKey(
      'console_{feature}_list-${query.isNotEmpty ? query : 'noq'}',
    );

    return NoTransitionPage<void>(
      key: pageKey,
      child: const Console{Feature}Page(),
    );
  }
}

3. RouteName Abstract Class Pattern#

/// {Feature} ๋ผ์šฐํŠธ ๊ฒฝ๋กœ ์ด๋ฆ„์„ ์ •์˜ํ•˜๋Š” ์ถ”์ƒ ํด๋ž˜์Šค
///
/// [path]๋Š” '/{feature}'๋กœ ์„ค์ •๋˜์–ด {feature} ํ™”๋ฉด์˜ ๊ฒฝ๋กœ๋กœ ์‚ฌ์šฉ๋ฉ๋‹ˆ๋‹ค.
abstract class {Feature}RouteName {
  /// {Feature} ํ™”๋ฉด ๋ผ์šฐํŠธ ๋ฒ ์ด์Šค
  static RouteBase get base => ${featureCamel}Route;

  /// {Feature} ํ™”๋ฉด ๋ผ์šฐํŠธ ๊ฒฝ๋กœ
  static const String path = '/{feature}';

  /// {Feature} ํ™”๋ฉด ๋ผ์šฐํŠธ ์ด๋ฆ„
  static const String name = '{feature}';
}

4. Nested Route Definition#

/// {Feature} ์ƒ์„ธ ํ™”๋ฉด ๋ผ์šฐํŠธ ์ •์˜
///
/// ์‹ค์ œ ๊ฒฝ๋กœ๋Š” '/{feature}/{id}'๊ฐ€ ๋ฉ๋‹ˆ๋‹ค.
@immutable
class {Feature}DetailRoute extends GoRouteData with ${Feature}DetailRoute {
  /// {Feature} ์ƒ์„ธ ํ™”๋ฉด ๋ผ์šฐํŠธ ์ƒ์„ฑ์ž
  const {Feature}DetailRoute({required this.id});

  /// ์กฐํšŒํ•  {feature}์˜ ID
  final int id;

  /// {Feature} ์ƒ์„ธ ํ™”๋ฉด ๋ผ์šฐํŠธ ๊ฒฝ๋กœ
  static const String path = ':id';

  @override
  FadeTransitionPage buildPage(BuildContext context, GoRouterState state) {
    // id์™€ ์ „์ฒด ์ฟผ๋ฆฌ ๋ฌธ์ž์—ด์„ ํฌํ•จํ•˜์—ฌ ๊ณ ์œ ํ•œ ํ‚ค ์ƒ์„ฑ
    final fullPath = state.uri.toString();
    final pageKey = ValueKey('{feature}Detail/$fullPath');

    return FadeTransitionPage(
      key: pageKey,
      child: {Feature}DetailPage(id: id),
    );
  }
}

5. Query Parameter Parsing Helpers#

/// ์ฟผ๋ฆฌ ํŒŒ๋ผ๋ฏธํ„ฐ์—์„œ ์ •์ˆ˜ ๊ฐ’์„ ํŒŒ์‹ฑํ•˜๋Š” ํ—ฌํผ ํ•จ์ˆ˜
int? _parseIntQueryParam(String? value) {
  return value != null ? int.tryParse(value) : null;
}

/// ์ฟผ๋ฆฌ ํŒŒ๋ผ๋ฏธํ„ฐ์—์„œ ๋ถˆ๋ฆฌ์–ธ ๊ฐ’์„ ํŒŒ์‹ฑํ•˜๋Š” ํ—ฌํผ ํ•จ์ˆ˜
bool _parseBoolQueryParam(String? value) {
  return value?.toLowerCase() == 'true';
}

6. Route Constants Definition#

/// ๋ผ์šฐํŠธ ์ƒ์ˆ˜ ์ •์˜ (private)
abstract class _RouteConstants {
  /// Detail ๋ผ์šฐํŠธ ์‹๋ณ„์ž
  static const String detail = 'detail';

  /// ํŽธ์ง‘ ๋ผ์šฐํŠธ ์‹๋ณ„์ž
  static const String edit = 'edit';

  /// ์ถ”๊ฐ€ ๋ผ์šฐํŠธ ์‹๋ณ„์ž
  static const String add = 'add';
}

Transition Page Types#

TypeClassWhere Used
FadeFadeTransitionPageApp general screens
SlideSlideTransitionPageModal, detail screens
NoneNoTransitionPageConsole, tab switching

Reference Files#

feature/application/store/lib/src/route/store_route.dart
feature/console/console_member_list/lib/src/route/console_member_list_route.dart
feature/application/app_router/lib/src/route/app_routes.dart
package/core/lib/src/transition/

Checklist#

  • TypedGoRoute Annotation Definition
  • GoRouteData extends + mixin Apply
  • Define RouteName abstract Class
  • Select appropriate transition Page
  • Generate unique ValueKey
  • Handle query parameters
  • Write KDoc comments
  • Connect .g.dart via part directive
  • build_runner Execution (melos run build)