Move apps to mobile directory structure

Relocated all app directories (client, design_system_viewer, staff) and their contents under the new 'apps/mobile' path. This change improves project organization and prepares for future platform-specific structuring.
This commit is contained in:
Achintha Isuru
2026-01-22 10:17:19 -05:00
parent 2f992ae5fa
commit cf59935ec8
982 changed files with 3 additions and 2532 deletions

View File

@@ -0,0 +1,60 @@
/// The Shared Domain Layer.
///
/// This package contains the core business entities and rules.
/// It is pure Dart and has no dependencies on Flutter or Firebase.
///
/// Note: Repository Interfaces are now located in their respective Feature packages.
// Users & Membership
export 'src/entities/users/user.dart';
export 'src/entities/users/staff.dart';
export 'src/entities/users/membership.dart';
export 'src/entities/users/biz_member.dart';
export 'src/entities/users/hub_member.dart';
// Business & Organization
export 'src/entities/business/business.dart';
export 'src/entities/business/business_setting.dart';
export 'src/entities/business/hub.dart';
export 'src/entities/business/hub_department.dart';
export 'src/entities/business/biz_contract.dart';
// Events & Shifts
export 'src/entities/events/event.dart';
export 'src/entities/events/event_shift.dart';
export 'src/entities/events/event_shift_position.dart';
export 'src/entities/events/assignment.dart';
export 'src/entities/events/work_session.dart';
// Skills & Certs
export 'src/entities/skills/skill.dart';
export 'src/entities/skills/skill_category.dart';
export 'src/entities/skills/staff_skill.dart';
export 'src/entities/skills/certificate.dart';
export 'src/entities/skills/skill_kit.dart';
// Financial & Payroll
export 'src/entities/financial/invoice.dart';
export 'src/entities/financial/invoice_item.dart';
export 'src/entities/financial/invoice_decline.dart';
export 'src/entities/financial/staff_payment.dart';
// Ratings & Penalties
export 'src/entities/ratings/staff_rating.dart';
export 'src/entities/ratings/penalty_log.dart';
export 'src/entities/ratings/business_staff_preference.dart';
// Staff Profile
export 'src/entities/profile/emergency_contact.dart';
export 'src/entities/profile/bank_account.dart';
export 'src/entities/profile/accessibility.dart';
export 'src/entities/profile/schedule.dart';
// Support & Config
export 'src/entities/support/addon.dart';
export 'src/entities/support/tag.dart';
export 'src/entities/support/media.dart';
export 'src/entities/support/working_area.dart';
// Home
export 'src/entities/home/home_dashboard_data.dart';

View File

@@ -0,0 +1,36 @@
import 'package:equatable/equatable.dart';
/// Represents a legal or service contract.
///
/// Can be between a business and the platform, or a business and staff.
class BizContract extends Equatable {
/// Unique identifier.
final String id;
/// The [Business] party to the contract.
final String businessId;
/// Descriptive name of the contract.
final String name;
/// Valid from date.
final DateTime startDate;
/// Valid until date (null if indefinite).
final DateTime? endDate;
/// URL to the document content (PDF/HTML).
final String contentUrl;
const BizContract({
required this.id,
required this.businessId,
required this.name,
required this.startDate,
this.endDate,
required this.contentUrl,
});
@override
List<Object?> get props => [id, businessId, name, startDate, endDate, contentUrl];
}

View File

@@ -0,0 +1,47 @@
import 'package:equatable/equatable.dart';
/// The operating status of a [Business].
enum BusinessStatus {
/// Business created but not yet approved.
pending,
/// Fully active and operational.
active,
/// Temporarily suspended (e.g. for non-payment).
suspended,
/// Permanently inactive.
inactive,
}
/// Represents a Client Company / Business.
///
/// This is the top-level organizational entity in the system.
class Business extends Equatable {
/// Unique identifier for the business.
final String id;
/// Display name of the business.
final String name;
/// Legal registration or tax number.
final String registrationNumber;
/// Current operating status.
final BusinessStatus status;
/// URL to the business logo.
final String? avatar;
const Business({
required this.id,
required this.name,
required this.registrationNumber,
required this.status,
this.avatar,
});
@override
List<Object?> get props => [id, name, registrationNumber, status, avatar];
}

View File

@@ -0,0 +1,41 @@
import 'package:equatable/equatable.dart';
/// Represents payroll and operational configuration for a [Business].
class BusinessSetting extends Equatable {
/// Unique identifier for the settings record.
final String id;
/// The [Business] these settings apply to.
final String businessId;
/// Prefix for generated invoices (e.g., "INV-").
final String prefix;
/// Whether overtime calculations are applied.
final bool overtimeEnabled;
/// Requirement method for clocking in (e.g. "qr_code", "geo_fence").
final String? clockInRequirement;
/// Requirement method for clocking out.
final String? clockOutRequirement;
const BusinessSetting({
required this.id,
required this.businessId,
required this.prefix,
required this.overtimeEnabled,
this.clockInRequirement,
this.clockOutRequirement,
});
@override
List<Object?> get props => [
id,
businessId,
prefix,
overtimeEnabled,
clockInRequirement,
clockOutRequirement,
];
}

View File

@@ -0,0 +1,46 @@
import 'package:equatable/equatable.dart';
/// The status of a [Hub].
enum HubStatus {
/// Fully operational.
active,
/// Closed or inactive.
inactive,
/// Not yet ready for operations.
underConstruction,
}
/// Represents a branch location or operational unit within a [Business].
class Hub extends Equatable {
/// Unique identifier.
final String id;
/// The parent [Business].
final String businessId;
/// Display name of the hub (e.g. "Downtown Branch").
final String name;
/// Physical address of this hub.
final String address;
/// Unique identifier of the NFC tag assigned to this hub.
final String? nfcTagId;
/// Operational status.
final HubStatus status;
const Hub({
required this.id,
required this.businessId,
required this.name,
required this.address,
this.nfcTagId,
required this.status,
});
@override
List<Object?> get props => [id, businessId, name, address, nfcTagId, status];
}

View File

@@ -0,0 +1,24 @@
import 'package:equatable/equatable.dart';
/// Represents a department within a [Hub].
///
/// Used for more granular organization of staff and events (e.g. "Kitchen", "Service").
class HubDepartment extends Equatable {
/// Unique identifier.
final String id;
/// The [Hub] this department belongs to.
final String hubId;
/// Name of the department.
final String name;
const HubDepartment({
required this.id,
required this.hubId,
required this.name,
});
@override
List<Object?> get props => [id, hubId, name];
}

View File

@@ -0,0 +1,58 @@
import 'package:equatable/equatable.dart';
/// The status of a staff [Assignment].
enum AssignmentStatus {
/// Staff member has been assigned but hasn't confirmed.
assigned,
/// Staff member has accepted the assignment.
confirmed,
/// Work is currently in progress (Clocked In).
ongoing,
/// Work completed successfully (Clocked Out).
completed,
/// Staff rejected the assignment offer.
declinedByStaff,
/// Staff canceled after accepting.
canceledByStaff,
/// Staff did not show up.
noShowed,
}
/// Represents the link between a [Staff] member and an [EventShiftPosition].
class Assignment extends Equatable {
/// Unique identifier.
final String id;
/// The job position being filled.
final String positionId;
/// The staff member filling the position.
final String staffId;
/// Current status of the assignment.
final AssignmentStatus status;
/// Actual timestamp when staff clocked in.
final DateTime? clockIn;
/// Actual timestamp when staff clocked out.
final DateTime? clockOut;
const Assignment({
required this.id,
required this.positionId,
required this.staffId,
required this.status,
this.clockIn,
this.clockOut,
});
@override
List<Object?> get props => [id, positionId, staffId, status, clockIn, clockOut];
}

View File

@@ -0,0 +1,70 @@
import 'package:equatable/equatable.dart';
/// The workflow status of an [Event].
enum EventStatus {
/// Created but incomplete.
draft,
/// Waiting for approval or publication.
pending,
/// Published and staff have been assigned.
assigned,
/// Fully confirmed and ready to start.
confirmed,
/// Currently in progress.
active,
/// Work has finished.
finished,
/// All post-event processes (invoicing) complete.
completed,
/// Archived.
closed,
/// Flagged for administrative review.
underReview,
}
/// Represents a Job Posting or Event.
///
/// This is the central entity for scheduling work. An Event contains [EventShift]s.
class Event extends Equatable {
/// Unique identifier.
final String id;
/// The [Business] hosting the event.
final String businessId;
/// The [Hub] location.
final String hubId;
/// Title of the event.
final String name;
/// Date of the event.
final DateTime date;
/// Current workflow status.
final EventStatus status;
/// Type of employment contract (e.g., 'freelance', 'permanent').
final String contractType;
const Event({
required this.id,
required this.businessId,
required this.hubId,
required this.name,
required this.date,
required this.status,
required this.contractType,
});
@override
List<Object?> get props => [id, businessId, hubId, name, date, status, contractType];
}

View File

@@ -0,0 +1,28 @@
import 'package:equatable/equatable.dart';
/// Represents a specific time block or "shift" within an [Event].
///
/// An Event can have multiple shifts (e.g. "Morning Shift", "Evening Shift").
class EventShift extends Equatable {
/// Unique identifier.
final String id;
/// The [Event] this shift belongs to.
final String eventId;
/// Descriptive name (e.g. "Setup Crew").
final String name;
/// Specific address for this shift (if different from Hub).
final String address;
const EventShift({
required this.id,
required this.eventId,
required this.name,
required this.address,
});
@override
List<Object?> get props => [id, eventId, name, address];
}

View File

@@ -0,0 +1,53 @@
import 'package:equatable/equatable.dart';
/// Represents a specific job opening within a [EventShift].
///
/// Defines the requirement for a specific [Skill], the quantity needed, and the pay.
class EventShiftPosition extends Equatable {
/// Unique identifier.
final String id;
/// The [EventShift] this position is part of.
final String shiftId;
/// The [Skill] required for this position.
final String skillId;
/// Number of staff needed.
final int count;
/// Hourly pay rate.
final double rate;
/// Start time of this specific position.
final DateTime startTime;
/// End time of this specific position.
final DateTime endTime;
/// Deducted break duration in minutes.
final int breakDurationMinutes;
const EventShiftPosition({
required this.id,
required this.shiftId,
required this.skillId,
required this.count,
required this.rate,
required this.startTime,
required this.endTime,
required this.breakDurationMinutes,
});
@override
List<Object?> get props => [
id,
shiftId,
skillId,
count,
rate,
startTime,
endTime,
breakDurationMinutes,
];
}

View File

@@ -0,0 +1,32 @@
import 'package:equatable/equatable.dart';
/// Represents a verified record of time worked.
///
/// Derived from [Assignment] clock-in/out times, used for payroll.
class WorkSession extends Equatable {
/// Unique identifier.
final String id;
/// The [Assignment] this session belongs to.
final String assignmentId;
/// Verified start time.
final DateTime startTime;
/// Verified end time.
final DateTime? endTime;
/// Verified break duration.
final int breakDurationMinutes;
const WorkSession({
required this.id,
required this.assignmentId,
required this.startTime,
this.endTime,
required this.breakDurationMinutes,
});
@override
List<Object?> get props => [id, assignmentId, startTime, endTime, breakDurationMinutes];
}

View File

@@ -0,0 +1,70 @@
import 'package:equatable/equatable.dart';
/// The workflow status of an [Invoice].
enum InvoiceStatus {
/// Generated but not yet sent/finalized.
open,
/// Client has disputed a line item.
disputed,
/// Dispute has been handled.
resolved,
/// Invoice accepted by client.
verified,
/// Payment received.
paid,
/// Payment reconciled in accounting.
reconciled,
/// Payment not received by due date.
overdue,
}
/// Represents a bill sent to a [Business] for services rendered.
class Invoice extends Equatable {
/// Unique identifier.
final String id;
/// The [Event] this invoice covers.
final String eventId;
/// The [Business] being billed.
final String businessId;
/// Current payment/approval status.
final InvoiceStatus status;
/// Grand total amount.
final double totalAmount;
/// Total amount for labor costs.
final double workAmount;
/// Total amount for addons/extras.
final double addonsAmount;
const Invoice({
required this.id,
required this.eventId,
required this.businessId,
required this.status,
required this.totalAmount,
required this.workAmount,
required this.addonsAmount,
});
@override
List<Object?> get props => [
id,
eventId,
businessId,
status,
totalAmount,
workAmount,
addonsAmount,
];
}

View File

@@ -0,0 +1,26 @@
import 'package:equatable/equatable.dart';
/// Represents a reason or log for a declined [Invoice].
class InvoiceDecline extends Equatable {
/// Unique identifier.
final String id;
/// The [Invoice] that was declined.
final String invoiceId;
/// Reason provided by the client.
final String reason;
/// When the decline happened.
final DateTime declinedAt;
const InvoiceDecline({
required this.id,
required this.invoiceId,
required this.reason,
required this.declinedAt,
});
@override
List<Object?> get props => [id, invoiceId, reason, declinedAt];
}

View File

@@ -0,0 +1,36 @@
import 'package:equatable/equatable.dart';
/// Represents a line item in an [Invoice].
///
/// Corresponds to the work done by one [Staff] member.
class InvoiceItem extends Equatable {
/// Unique identifier.
final String id;
/// The [Invoice] this item belongs to.
final String invoiceId;
/// The [Staff] member whose work is being billed.
final String staffId;
/// Total billed hours.
final double workHours;
/// Hourly rate applied.
final double rate;
/// Total line item amount (workHours * rate).
final double amount;
const InvoiceItem({
required this.id,
required this.invoiceId,
required this.staffId,
required this.workHours,
required this.rate,
required this.amount,
});
@override
List<Object?> get props => [id, invoiceId, staffId, workHours, rate, amount];
}

View File

@@ -0,0 +1,49 @@
import 'package:equatable/equatable.dart';
/// Status of a staff payout.
enum PaymentStatus {
/// Payout calculated but not processed.
pending,
/// Submitted to banking provider.
processing,
/// Successfully transferred to staff.
paid,
/// Transfer failed.
failed,
}
/// Represents a payout to a [Staff] member for a completed [Assignment].
class StaffPayment extends Equatable {
/// Unique identifier.
final String id;
/// The recipient [Staff].
final String staffId;
/// The [Assignment] being paid for.
final String assignmentId;
/// Amount to be paid.
final double amount;
/// Processing status.
final PaymentStatus status;
/// When the payment was successfully processed.
final DateTime? paidAt;
const StaffPayment({
required this.id,
required this.staffId,
required this.assignmentId,
required this.amount,
required this.status,
this.paidAt,
});
@override
List<Object?> get props => [id, staffId, assignmentId, amount, status, paidAt];
}

View File

@@ -0,0 +1,45 @@
import 'package:equatable/equatable.dart';
/// Entity representing dashboard data for the home screen.
///
/// This entity provides aggregated metrics such as spending and shift counts
/// for both the current week and the upcoming 7 days.
class HomeDashboardData extends Equatable {
/// Total spending for the current week.
final double weeklySpending;
/// Projected spending for the next 7 days.
final double next7DaysSpending;
/// Total shifts scheduled for the current week.
final int weeklyShifts;
/// Shifts scheduled for the next 7 days.
final int next7DaysScheduled;
/// Total workers needed for today's shifts.
final int totalNeeded;
/// Total workers filled for today's shifts.
final int totalFilled;
/// Creates a [HomeDashboardData] instance.
const HomeDashboardData({
required this.weeklySpending,
required this.next7DaysSpending,
required this.weeklyShifts,
required this.next7DaysScheduled,
required this.totalNeeded,
required this.totalFilled,
});
@override
List<Object?> get props => [
weeklySpending,
next7DaysSpending,
weeklyShifts,
next7DaysScheduled,
totalNeeded,
totalFilled,
];
}

View File

@@ -0,0 +1,20 @@
import 'package:equatable/equatable.dart';
/// Represents accessibility requirements or features.
///
/// Can apply to Staff (needs) or Events (provision).
class Accessibility extends Equatable {
/// Unique identifier.
final String id;
/// Description (e.g. "Wheelchair Access").
final String name;
const Accessibility({
required this.id,
required this.name,
});
@override
List<Object?> get props => [id, name];
}

View File

@@ -0,0 +1,34 @@
import 'package:equatable/equatable.dart';
/// Represents bank account details for payroll.
class BankAccount extends Equatable {
/// Unique identifier.
final String id;
/// The [User] owning the account.
final String userId;
/// Name of the bank.
final String bankName;
/// Account number.
final String accountNumber;
/// Name on the account.
final String accountName;
/// Sort code (if applicable).
final String? sortCode;
const BankAccount({
required this.id,
required this.userId,
required this.bankName,
required this.accountNumber,
required this.accountName,
this.sortCode,
});
@override
List<Object?> get props => [id, userId, bankName, accountNumber, accountName, sortCode];
}

View File

@@ -0,0 +1,24 @@
import 'package:equatable/equatable.dart';
/// Represents an emergency contact for a user.
///
/// Critical for staff safety during shifts.
class EmergencyContact extends Equatable {
/// Full name of the contact.
final String name;
/// Relationship to the user (e.g. "Spouse", "Parent").
final String relationship;
/// Phone number.
final String phone;
const EmergencyContact({
required this.name,
required this.relationship,
required this.phone,
});
@override
List<Object?> get props => [name, relationship, phone];
}

View File

@@ -0,0 +1,32 @@
import 'package:equatable/equatable.dart';
/// Represents general availability schedule for a [Staff] member.
///
/// Defines recurring availability (e.g., "Mondays 9-5").
class Schedule extends Equatable {
/// Unique identifier.
final String id;
/// The [Staff] member.
final String staffId;
/// Day of the week (1 = Monday, 7 = Sunday).
final int dayOfWeek;
/// Start time of availability.
final DateTime startTime;
/// End time of availability.
final DateTime endTime;
const Schedule({
required this.id,
required this.staffId,
required this.dayOfWeek,
required this.startTime,
required this.endTime,
});
@override
List<Object?> get props => [id, staffId, dayOfWeek, startTime, endTime];
}

View File

@@ -0,0 +1,35 @@
import 'package:equatable/equatable.dart';
/// The type of preference a business has for a staff member.
enum PreferenceType {
/// Business wants to prioritize this staff member.
favorite,
/// Business does not want to work with this staff member.
blocked,
}
/// Represents a business's specific preference for a staff member.
class BusinessStaffPreference extends Equatable {
/// Unique identifier.
final String id;
/// The [Business] holding the preference.
final String businessId;
/// The [Staff] member.
final String staffId;
/// Whether they are a favorite or blocked.
final PreferenceType type;
const BusinessStaffPreference({
required this.id,
required this.businessId,
required this.staffId,
required this.type,
});
@override
List<Object?> get props => [id, businessId, staffId, type];
}

View File

@@ -0,0 +1,36 @@
import 'package:equatable/equatable.dart';
/// Represents a penalty issued to a staff member.
///
/// Penalties are issued for no-shows, cancellations, or poor conduct.
class PenaltyLog extends Equatable {
/// Unique identifier.
final String id;
/// The [Staff] member penalized.
final String staffId;
/// The [Assignment] context (if applicable).
final String assignmentId;
/// Reason for the penalty.
final String reason;
/// Score points deducted from staff profile.
final int points;
/// When the penalty was issued.
final DateTime issuedAt;
const PenaltyLog({
required this.id,
required this.staffId,
required this.assignmentId,
required this.reason,
required this.points,
required this.issuedAt,
});
@override
List<Object?> get props => [id, staffId, assignmentId, reason, points, issuedAt];
}

View File

@@ -0,0 +1,34 @@
import 'package:equatable/equatable.dart';
/// Represents a rating given to a staff member by a client.
class StaffRating extends Equatable {
/// Unique identifier.
final String id;
/// The [Staff] being rated.
final String staffId;
/// The [Event] context.
final String eventId;
/// The [Business] leaving the rating.
final String businessId;
/// Star rating (1-5).
final int rating;
/// Optional feedback text.
final String? comment;
const StaffRating({
required this.id,
required this.staffId,
required this.eventId,
required this.businessId,
required this.rating,
this.comment,
});
@override
List<Object?> get props => [id, staffId, eventId, businessId, rating, comment];
}

View File

@@ -0,0 +1,24 @@
import 'package:equatable/equatable.dart';
/// Represents a required certificate definition.
///
/// Examples: "Food Hygiene Level 2", "SIA Badge".
class Certificate extends Equatable {
/// Unique identifier.
final String id;
/// Display name of the certificate.
final String name;
/// Whether this certificate is mandatory for platform access or specific roles.
final bool isRequired;
const Certificate({
required this.id,
required this.name,
required this.isRequired,
});
@override
List<Object?> get props => [id, name, isRequired];
}

View File

@@ -0,0 +1,29 @@
import 'package:equatable/equatable.dart';
/// Represents a job category / skill type.
///
/// Examples: "Waiter", "Security Guard", "Bartender".
/// Linked to a [SkillCategory].
class Skill extends Equatable {
/// Unique identifier.
final String id;
/// The broader category (e.g. "Hospitality").
final String categoryId;
/// Display name of the skill.
final String name;
/// Default hourly rate suggested for this skill.
final double basePrice;
const Skill({
required this.id,
required this.categoryId,
required this.name,
required this.basePrice,
});
@override
List<Object?> get props => [id, categoryId, name, basePrice];
}

View File

@@ -0,0 +1,18 @@
import 'package:equatable/equatable.dart';
/// Represents a broad category of skills (e.g. "Hospitality", "Logistics").
class SkillCategory extends Equatable {
/// Unique identifier.
final String id;
/// Display name.
final String name;
const SkillCategory({
required this.id,
required this.name,
});
@override
List<Object?> get props => [id, name];
}

View File

@@ -0,0 +1,32 @@
import 'package:equatable/equatable.dart';
/// Represents required equipment or uniform for a specific [Skill].
///
/// Examples: "Black Shirt" (Uniform), "Safety Boots" (Equipment).
class SkillKit extends Equatable {
/// Unique identifier.
final String id;
/// The [Skill] this kit applies to.
final String skillId;
/// Description of the item.
final String name;
/// Whether the staff member MUST possess this item.
final bool isRequired;
/// Type of kit ('uniform' or 'equipment').
final String type;
const SkillKit({
required this.id,
required this.skillId,
required this.name,
required this.isRequired,
required this.type,
});
@override
List<Object?> get props => [id, skillId, name, isRequired, type];
}

View File

@@ -0,0 +1,58 @@
import 'package:equatable/equatable.dart';
/// The expertise level of a staff member in a specific skill.
enum SkillLevel {
/// Entry level.
beginner,
/// Experienced.
skilled,
/// Expert / Managerial level.
professional,
}
/// The verification status of a claimed skill.
enum StaffSkillStatus {
/// Claimed by staff, waiting for admin approval.
pending,
/// Verified by admin (documents checked).
verified,
/// Rejected by admin.
rejected,
}
/// Represents a staff member's qualification in a specific [Skill].
class StaffSkill extends Equatable {
/// Unique identifier.
final String id;
/// The [Staff] member.
final String staffId;
/// The [Skill] they possess.
final String skillId;
/// Their expertise level.
final SkillLevel level;
/// Years of experience.
final int experienceYears;
/// Verification status.
final StaffSkillStatus status;
const StaffSkill({
required this.id,
required this.staffId,
required this.skillId,
required this.level,
required this.experienceYears,
required this.status,
});
@override
List<Object?> get props => [id, staffId, skillId, level, experienceYears, status];
}

View File

@@ -0,0 +1,26 @@
import 'package:equatable/equatable.dart';
/// Represents a financial addon/bonus/deduction applied to an Invoice or Payment.
class Addon extends Equatable {
/// Unique identifier.
final String id;
/// Description (e.g. "Travel Expense").
final String name;
/// Monetary value.
final double amount;
/// Type ('credit' or 'debit').
final String type;
const Addon({
required this.id,
required this.name,
required this.amount,
required this.type,
});
@override
List<Object?> get props => [id, name, amount, type];
}

View File

@@ -0,0 +1,24 @@
import 'package:equatable/equatable.dart';
/// Represents a media file reference.
///
/// Used for avatars, certificates, or event photos.
class Media extends Equatable {
/// Unique identifier.
final String id;
/// External URL to the file.
final String url;
/// MIME type or general type (image, pdf).
final String type;
const Media({
required this.id,
required this.url,
required this.type,
});
@override
List<Object?> get props => [id, url, type];
}

View File

@@ -0,0 +1,18 @@
import 'package:equatable/equatable.dart';
/// Represents a descriptive tag used for categorizing events or staff.
class Tag extends Equatable {
/// Unique identifier.
final String id;
/// Text label.
final String label;
const Tag({
required this.id,
required this.label,
});
@override
List<Object?> get props => [id, label];
}

View File

@@ -0,0 +1,30 @@
import 'package:equatable/equatable.dart';
/// Represents a geographical area where a [Staff] member is willing to work.
class WorkingArea extends Equatable {
/// Unique identifier.
final String id;
/// Name of the area (e.g. "London Zone 1").
final String name;
/// Latitude of the center point.
final double centerLat;
/// Longitude of the center point.
final double centerLng;
/// Radius in Kilometers.
final double radiusKm;
const WorkingArea({
required this.id,
required this.name,
required this.centerLat,
required this.centerLng,
required this.radiusKm,
});
@override
List<Object?> get props => [id, name, centerLat, centerLng, radiusKm];
}

View File

@@ -0,0 +1,28 @@
import 'package:equatable/equatable.dart';
/// Represents a member of a Business.
///
/// Grants a user access to business-level operations.
class BizMember extends Equatable {
/// Unique identifier for this membership.
final String id;
/// The [Business] the user belongs to.
final String businessId;
/// The [User] who is a member.
final String userId;
/// The role within the business.
final String role;
const BizMember({
required this.id,
required this.businessId,
required this.userId,
required this.role,
});
@override
List<Object?> get props => [id, businessId, userId, role];
}

View File

@@ -0,0 +1,28 @@
import 'package:equatable/equatable.dart';
/// Represents a member of a Hub.
///
/// Grants a user access to specific [Hub] operations, distinct from [BizMember].
class HubMember extends Equatable {
/// Unique identifier for this membership.
final String id;
/// The [Hub] the user belongs to.
final String hubId;
/// The [User] who is a member.
final String userId;
/// The role within the hub.
final String role;
const HubMember({
required this.id,
required this.hubId,
required this.userId,
required this.role,
});
@override
List<Object?> get props => [id, hubId, userId, role];
}

View File

@@ -0,0 +1,32 @@
import 'package:equatable/equatable.dart';
/// Represents a polymorphic membership to an organization unit.
///
/// Allows a [User] to be a member of either a [Business] or a [Hub].
class Membership extends Equatable {
/// Unique identifier for the membership record.
final String id;
/// The [User] holding this membership.
final String userId;
/// The ID of the organization unit (Business or Hub).
final String memberableId;
/// The type of the organization unit ('business' or 'hub').
final String memberableType;
/// The role within that organization (e.g., 'manager', 'viewer').
final String role;
const Membership({
required this.id,
required this.userId,
required this.memberableId,
required this.memberableType,
required this.role,
});
@override
List<Object?> get props => [id, userId, memberableId, memberableType, role];
}

View File

@@ -0,0 +1,83 @@
import 'package:equatable/equatable.dart';
/// The lifecycle status of a [Staff] account.
enum StaffStatus {
/// Account created but profile not started.
registered,
/// Profile submitted and awaiting verification.
pending,
/// Profile information filled but not submitted for verification.
completedProfile,
/// Profile verified by admin.
verified,
/// Staff is currently active and eligible for work.
active,
/// Account is temporarily suspended.
blocked,
/// Account is permanently inactive.
inactive,
}
/// Represents a worker profile.
///
/// Contains all personal and professional details of a staff member.
/// Linked to a [User] via [authProviderId].
class Staff extends Equatable {
/// Unique identifier for the staff profile.
final String id;
/// Link to the [User] authentication record.
final String authProviderId;
/// Full display name.
final String name;
/// Contact email.
final String email;
/// Contact phone number.
final String? phone;
/// Current workflow status of the staff member.
final StaffStatus status;
/// Physical address string.
final String? address;
/// URL to the avatar image.
final String? avatar;
/// URL to a verified live photo for identity verification.
final String? livePhoto;
const Staff({
required this.id,
required this.authProviderId,
required this.name,
required this.email,
this.phone,
required this.status,
this.address,
this.avatar,
this.livePhoto,
});
@override
List<Object?> get props => [
id,
authProviderId,
name,
email,
phone,
status,
address,
avatar,
livePhoto,
];
}

View File

@@ -0,0 +1,30 @@
import 'package:equatable/equatable.dart';
/// Represents a base authenticated user in the KROW platform.
///
/// This entity corresponds to the Firebase Auth user record and acts as the
/// linkage between the authentication system and the specific [Staff] or Client profiles.
class User extends Equatable {
/// The unique identifier from the authentication provider (e.g., Firebase UID).
final String id;
/// The user's email address.
final String email;
/// The user's phone number, if available.
final String? phone;
/// The primary role of the user (e.g., 'staff', 'client_admin').
/// This determines the initial routing and permissions.
final String role;
const User({
required this.id,
required this.email,
this.phone,
required this.role,
});
@override
List<Object?> get props => [id, email, phone, role];
}

View File

@@ -0,0 +1,11 @@
name: krow_domain
description: Domain entities and business logic.
version: 0.0.1
publish_to: none
resolution: workspace
environment:
sdk: '>=3.10.0 <4.0.0'
dependencies:
equatable: ^2.0.8