← Code knowledge base
Reviewed Flutter implementation · 2026-10-27

card_pin_policy.dart

mobile_flutter/lib/features/cards/domain/card_pin_policy.dart

Immutable source snapshot based on revision de78e63ed65c. Original line numbers are retained. This is implementation evidence; check the public API catalogue before adapting it.

The mobile /api/v1/mobile routes belong to the example backend. Company credentials stay on that backend. Some sections outside the documented product scope may be omitted.

Lines 1–61

/// Card PIN rules, mirrored from the backend (`CardPinPolicy`): exactly six/// digits, not a single repeated digit, not a run of consecutive digits up or/// down (including 890123 / 210987), and not a short block repeated to fill/// the PIN (121212, 123123).const cardPinLength = 6; class CardPinRule {  const CardPinRule(this.label, this.test);   final String label;  final bool Function(String pin) test;} const cardPinRules = [  CardPinRule('Exactly 6 digits', _isSixDigits),  CardPinRule('Not one repeated digit (111111)', _notSingleDigit),  CardPinRule('Not a run of digits (123456, 654321)', _notSequential),  CardPinRule('Not a repeating pattern (121212, 123123)', _notRepeatedBlock),]; bool cardPinMeetsPolicy(String pin) =>    cardPinRules.every((rule) => rule.test(pin)); /// The first unmet rule, or null when the PIN is acceptable.String? cardPinProblem(String pin) {  for (final rule in cardPinRules) {    if (!rule.test(pin)) return rule.label;  }  return null;} final _sixDigits = RegExp(r'^[0-9]{6}$'); bool _isSixDigits(String pin) => _sixDigits.hasMatch(pin); bool _notSingleDigit(String pin) =>    pin.isEmpty || pin.split('').toSet().length > 1; bool _notSequential(String pin) {  if (pin.length < 2) return true;  var ascending = true;  var descending = true;  for (var i = 1; i < pin.length; i++) {    final step = (pin.codeUnitAt(i) - pin.codeUnitAt(i - 1)) % 10;    ascending &= step == 1;    descending &= step == 9;  }  return !(ascending || descending);} bool _notRepeatedBlock(String pin) {  for (var block = 1; block <= pin.length ~/ 2; block++) {    if (pin.length % block != 0) continue;    var repeated = true;    for (var i = block; i < pin.length && repeated; i++) {      repeated = pin[i] == pin[i - block];    }    if (repeated) return false;  }  return true;}
HOPPA DEVELOPER ASSISTANT

What are you building?

From a question to an implementation.

Get a step-by-step flow, example code and the docs behind it. Choose a starting point or describe your feature.

Answers use the public API guide and example app code. Check the linked reference before shipping. Explore code sources ↗

Your question and recent conversation are sent to our AI provider. Don’t include API keys, personal data or card details.