-
Notifications
You must be signed in to change notification settings - Fork 1
Data Models
Garot Conklin edited this page Dec 17, 2024
·
2 revisions
This document details the data models used throughout the RunOn! application, including database schemas, API DTOs, and domain models.
data class Event(
val id: String,
val title: String,
val description: String,
val date: LocalDateTime,
val location: Location,
val distance: Distance,
val eventType: EventType,
val organizer: Organizer,
val price: Price?,
val registrationDeadline: LocalDateTime?,
val participantLimit: Int?,
val currentParticipants: Int,
val status: EventStatus,
val tags: List<String>,
val imageUrl: String?,
val websiteUrl: String?,
val createdAt: Instant,
val updatedAt: Instant
)
data class Location(
val name: String,
val address: String,
val city: String,
val state: String,
val country: String,
val postalCode: String,
val coordinates: Coordinates
)
data class Coordinates(
val latitude: Double,
val longitude: Double
)
data class Distance(
val value: Double,
val unit: DistanceUnit
)
enum class DistanceUnit {
KILOMETERS,
MILES
}
enum class EventType {
RACE,
FUN_RUN,
TRAINING,
CHARITY,
ULTRA,
TRAIL,
TRACK
}
enum class EventStatus {
UPCOMING,
ONGOING,
COMPLETED,
CANCELLED,
SOLD_OUT
}data class User(
val id: String,
val email: String,
val profile: UserProfile,
val preferences: UserPreferences,
val stats: UserStats,
val createdAt: Instant,
val updatedAt: Instant
)
data class UserProfile(
val displayName: String,
val firstName: String?,
val lastName: String?,
val bio: String?,
val avatarUrl: String?,
val location: Location?
)
data class UserPreferences(
val preferredDistances: List<Distance>,
val preferredEventTypes: List<EventType>,
val maxTravelDistance: Distance,
val preferredLocation: Location?,
val notificationSettings: NotificationSettings
)
data class UserStats(
val eventsParticipated: Int,
val totalDistance: Distance,
val achievements: List<Achievement>
){
"_id": "ObjectId",
"auth0Id": "string",
"email": "string",
"profile": {
"name": "string",
"location": {
"type": "Point",
"coordinates": [longitude, latitude]
},
"preferences": {
"searchRadius": "number",
"eventTypes": ["string"],
"notifications": "boolean"
}
},
"calendar": {
"googleCalendarId": "string?",
"syncEnabled": "boolean"
},
"createdAt": "ISODate",
"updatedAt": "ISODate"
}{
"_id": "ObjectId",
"sourceId": "string",
"source": "enum('google', 'manual', 'partner')",
"title": "string",
"description": "string",
"location": {
"type": "Point",
"coordinates": [longitude, latitude],
"address": "string"
},
"date": {
"start": "ISODate",
"end": "ISODate"
},
"type": "string",
"url": "string",
"metadata": {
"distance": "string?",
"terrain": "string?",
"difficulty": "string?",
"price": "number?"
},
"createdAt": "ISODate",
"updatedAt": "ISODate"
}{
"_id": "ObjectId",
"userId": "ObjectId",
"eventId": "ObjectId",
"status": "enum('interested', 'registered', 'completed')",
"calendarSync": "boolean",
"notes": "string?",
"createdAt": "ISODate",
"updatedAt": "ISODate"
}// Key: event:{eventId}
// TTL: 15 minutes
interface EventCache {
id: string;
title: string;
date: ISOString;
location: {
lat: number;
lng: number;
address: string;
};
}// Key: search:{location}:{radius}:{types}
// TTL: 5 minutes
interface SearchCache {
events: string[]; // Array of event IDs
timestamp: ISOString;
}// Key: user:{userId}:preferences
// TTL: 1 hour
interface PreferencesCache {
location: {
lat: number;
lng: number;
radius: number;
};
eventTypes: string[];
}interface EventResponse {
id: string;
title: string;
description: string;
date: {
start: ISOString;
end: ISOString;
};
location: {
lat: number;
lng: number;
address: string;
};
type: string;
url: string;
metadata?: {
distance?: string;
terrain?: string;
difficulty?: string;
price?: number;
};
}interface SearchResponse {
events: EventResponse[];
pagination: {
total: number;
page: number;
pageSize: number;
hasMore: boolean;
};
metadata: {
location: {
lat: number;
lng: number;
radius: number;
};
filters: {
types: string[];
dateRange?: {
start: ISOString;
end: ISOString;
};
};
};
}// Events Collection
db.events.createIndex({ "location": "2dsphere" });
db.events.createIndex({ "date.start": 1 });
db.events.createIndex({ "sourceId": 1 }, { unique: true });
// Users Collection
db.users.createIndex({ "auth0Id": 1 }, { unique: true });
db.users.createIndex({ "profile.location": "2dsphere" });
// UserEvents Collection
db.userEvents.createIndex({ "userId": 1, "eventId": 1 }, { unique: true });
db.userEvents.createIndex({ "userId": 1, "status": 1 });{
validator: {
$jsonSchema: {
bsonType: "object",
required: ["title", "date", "location"],
properties: {
title: {
bsonType: "string",
description: "must be a string and is required"
},
location: {
bsonType: "object",
required: ["type", "coordinates"],
properties: {
type: { enum: ["Point"] },
coordinates: {
bsonType: ["array"],
minItems: 2,
maxItems: 2,
items: { bsonType: "double" }
}
}
}
}
}
}
}{
"_id": "ObjectId",
"version": "number",
"appliedAt": "ISODate",
"description": "string"
}- Daily automated backups
- Point-in-time recovery enabled
- 7-day retention period
- Cross-region backup for disaster recovery
© RunOn! 2024
Full-Featured Documentation
- Android Technical Stack (Archived)
- Android Architecture (Archived)
- Business Prospectus (Archived)
- Feature Specifications (Archived)
- UI/UX Design (Archived)