Project (in Media)
You can think of a project as a folder filled with assets and details about what the assets are, who has access, how do assets related to each other and so much more.
Task Chat Branch EndpointThis document is not meant to outline how to use the API endpoints, rather how to build it. We outline what it's capabilities should be, once you have built them, you can creat documentation on how to utilize them on the APIs tab.
- Status & Details
- User Stories, Flows & Personas
- Features & Functions
- Data
Description
A Project can be a music album filled with fun facts about how ti was made, some details shared with the public and some are meant for personal memories or to plan how it will be made, where is the artist recording track 1 and where is the music video being filmed, perhaps thats a lot of information, another project can be linked just for the video or a sub-project can be created, it truly behaves like a folder. Now for the assets, perhaps you have a podcast and you have assets for voiceovers, subtitles, sound afects and so much more.
Status
These details are only updated with each release, for more acurate updates and keeping track of progress, see the task in GitHub.
| Owner | Lead | Doc Status | Product Status | Last Update | Version | Release | Phase |
|---|---|---|---|---|---|---|---|
| Mendy | Polina | In Progress | Released | 29.03.2025 | 0.01 | Internal | Alpha |
Next Steps
- Implement search endpoints and filters.
- Enhance API security for authentication.
- Add role-based access control.
Reminders
- Keep code lean and clear
- follow the outlined arcetecture
- write commetes in your code
- update the staus in the docs and in GitHub
- try not to recreate functions we alredy have, rather update exsiting functions to support your needs
- Be sure to follow the release guidelines
- Update Documentation
- keep API docs up to date each time you update or add endpoints
Links & Resources
User Stories
Details
Persona One
I'm a creator and want to share my contentDetails
Persona Two
As a user I would like to plan my filming schedual and assign my firends or emplyees to tasks, locations, equpment, etc.Details
Persona Three
As a social media manager I wamt to hire a translator, assign the project and have them add subtitles in many langaguesDetails
Persona Four
I'm starting a podcast, i want to group all my knowledge and resources in one place, I have a friend who id helping me but I'm not ready to share all my information, I want to create a project only for one episode and keep it together with the rest of the podcast details and easily move assets, details and other resources Between the projects.User Flows
Personas
Features
Below is a list of features that will be utilized in order to deliver the best account features and functionalities. The details bellow are not comprehensive feature details but rather, describe how the features will be utilized within the account, for further details, please see the individual feature documentation.
-
[Permissions]
I want to assign permissions and work together on a project
I want to publish my project once it is complete, I want to choose what the final version or asset is, i want to choose what details are publish and what stays private, I want to choose where I publish it (by default only on the Clients' Media Channel but the Client can allow publishing on other Media Channels such as facebook, instagram, etc. the clients can also enable Republish, meaning it is published on the Clients' channel but a link and some details are shared to other Media Channels or moromo publish meaning a short trailer that is prepared in advanced or AI is shared on all media chaneels)
-
[collaborations]
I want to ad another channel that is featured
-
[Split revenue]
I want to add producers, partners, collaborators and assign a percentage of revenue that should go to them, I also want to uplaod or create an agreement and i want to be able to prove they reviced thier share in case we ever go to court
-
Follow
channels can follow other channels and see thier content in thier feed
-
Notifications
channels can choose to recive notifications for channels they follow
-
Privacy
a channel can choose to make thier channel private by invite, allow to find if they have thier email or number, publish, when private only invites can follow, only followers can see thier content or only people with thier
-
Revenue
the channel can choose how they want to earn from this project, they can sell with ads, rent with ads, rent no ads, sell no ads, add to membership, make free with ads, or free without ads, add to bundle sale, there will be more option in the future, we should also allow the client to develop thier own sales method
-
Promote
allow the channel to create promotion assets, scredual posts, asibly a sub-project just for promotion purposes
Data
To understand how collections and documents work, see Data Sctructure
On the main document we want to keep all the important data, the first fetch and fast to access.
- Structure
- Model
- Project/Content
-
- project1
-
-
- project_type_id (project, show, album, Podcasts, Playlist)(project, music, Show, Podcasts, Playlist, radio)
-
-
-
- sub_type_id (Episode, Album, song, single, )
-
-
-
- channelID (project cannot exist without a channel, and build API to get all projects of a specific channel, we need channelID in projects.)
-
-
-
- primary_title
-
-
-
- description` text
-
-
-
- portrait_img` (asset link)
-
-
-
- landscape_img` varchL,
-
-
-
- access_types (inharited, permissions, link private, public link') //how can this be accessed
-
-
-
- public_status` (private, link, published) //sttus of public link
-
-
-
- project status (draft, active, archived, soft delete, hard delete/volt) //status of project
-
-
-
- primary_language (id)
-
-
-
- category (id)
-
-
-
- sub_category (id)
-
-
-
- topics (IDs)
-
-
-
- location
-
-
-
- release date
-
-
-
- supported_formats (audio, video, text) allow multiple
-
-
-
- supported _modes (read, listen, watch, chat, go) allow multiple
-
-
-
- supported_features (comments, remix, like/dislike/votes, poles, download, translate, ent/transcribe, voiceover, etc) allow multiple
-
-
-
- release date (DateTime)
-
-
-
- location
-
Let's create a Dart Firestore model based on your requirements. I'll structure it using Dart classes and include appropriate data types and comments for clarity.
// Enum definitions for controlled vocabularies
enum ProjectType { project, show, album, podcasts, playlist }
enum ContentUploadType { serverVideo, externalUrl, youtube }
enum AccessType { public, permissions, linkPrivate }
enum Status { draft, published, archived } // Example statuses, adjust as needed
enum FormatType { audio, video, text }
enum ModeType { read, listen, watch, chat, go }
enum FeatureType {
comments,
remix,
likeDislikeVotes,
polls,
download,
translate,
entTranscribe,
voiceover
}
class Project {
final String id; // Firestore document ID
final ProjectType projectTypeId;
final String? subTypeId; // Optional subtype
final String primaryTitle;
final String description;
final String portraitImg; // URL or storage reference
final String landscapeImg; // URL or storage reference
final ContentUploadType contentUploadType;
final AccessType access;
final Status status;
final String primaryLanguageId; // Reference to language collection
final String categoryId; // Reference to category collection
final String? subCategoryId; // Optional, reference to subcategory
final List<String> topicIds; // Array of topic references
final List<FormatType> supportedFormats; // Multiple formats allowed
final List<ModeType> supportedModes; // Multiple modes allowed
final List<FeatureType> supportedFeatures; // Multiple features allowed
final DateTime createdAt; // Timestamp for creation
final DateTime updatedAt; // Timestamp for last update
Project({
required this.id,
required this.projectTypeId,
this.subTypeId,
required this.primaryTitle,
required this.description,
required this.portraitImg,
required this.landscapeImg,
required this.contentUploadType,
required this.access,
required this.status,
required this.primaryLanguageId,
required this.categoryId,
this.subCategoryId,
required this.topicIds,
required this.supportedFormats,
required this.supportedModes,
required this.supportedFeatures,
required this.createdAt,
required this.updatedAt,
});
// Convert Project object to Firestore map
Map<String, dynamic> toFirestore() {
return {
'project_type_id': projectTypeId.name,
'sub_type_id': subTypeId,
'primary_title': primaryTitle,
'description': description,
'portrait_img': portraitImg,
'landscape_img': landscapeImg,
'content_upload_type': contentUploadType.name,
'access': access.name,
'status': status.name,
'primary_language_id': primaryLanguageId,
'category_id': categoryId,
'sub_category_id': subCategoryId,
'topic_ids': topicIds,
'supported_formats': supportedFormats.map((e) => e.name).toList(),
'supported_modes': supportedModes.map((e) => e.name).toList(),
'supported_features': supportedFeatures.map((e) => e.name).toList(),
'created_at': createdAt.toIso8601String(),
'updated_at': updatedAt.toIso8601String(),
};
}
// Create Project object from Firestore document
factory Project.fromFirestore(Map<String, dynamic> data, String documentId) {
return Project(
id: documentId,
projectTypeId: ProjectType.values.firstWhere(
(e) => e.name == data['project_type_id'],
),
subTypeId: data['sub_type_id'],
primaryTitle: data['primary_title'],
description: data['description'],
portraitImg: data['portrait_img'],
landscapeImg: data['landscape_img'],
contentUploadType: ContentUploadType.values.firstWhere(
(e) => e.name == data['content_upload_type'],
),
access: AccessType.values.firstWhere(
(e) => e.name == data['access'],
),
status: Status.values.firstWhere(
(e) => e.name == data['status'],
),
primaryLanguageId: data['primary_language_id'],
categoryId: data['category_id'],
subCategoryId: data['sub_category_id'],
topicIds: List<String>.from(data['topic_ids'] ?? []),
supportedFormats: (data['supported_formats'] as List<dynamic>)
.map((e) => FormatType.values.firstWhere((f) => f.name == e))
.toList(),
supportedModes: (data['supported_modes'] as List<dynamic>)
.map((e) => ModeType.values.firstWhere((m) => m.name == e))
.toList(),
supportedFeatures: (data['supported_features'] as List<dynamic>)
.map((e) => FeatureType.values.firstWhere((f) => f.name == e))
.toList(),
createdAt: DateTime.parse(data['created_at']),
updatedAt: DateTime.parse(data['updated_at']),
);
}
}
// Example usage:
void exampleUsage() {
final project = Project(
id: 'project1',
projectTypeId: ProjectType.project,
primaryTitle: 'My First Project',
description: 'A sample project description',
portraitImg: 'https://example.com/portrait.jpg',
landscapeImg: 'https://example.com/landscape.jpg',
contentUploadType: ContentUploadType.serverVideo,
access: AccessType.public,
status: Status.draft,
primaryLanguageId: 'lang1',
categoryId: 'cat1',
topicIds: ['topic1', 'topic2'],
supportedFormats: [FormatType.video, FormatType.audio],
supportedModes: [ModeType.watch, ModeType.listen],
supportedFeatures: [FeatureType.comments, FeatureType.download],
createdAt: DateTime.now(),
updatedAt: DateTime.now(),
);
// Convert to Firestore format
final firestoreData = project.toFirestore();
}
This Dart Firestore model includes:
- Enum types for controlled vocabularies (ProjectType, ContentUploadType, etc.)
- A main Project class with all required fields
- Type safety with appropriate Dart types
- Methods to convert to/from Firestore format
- Support for multiple selections (formats, modes, features) using Lists
- Timestamp fields for creation and updates
- Nullable fields where appropriate (subTypeId, subCategoryId)
Notes:
- I've added createdAt and updatedAt fields which are common in Firestore models
- The model uses references (IDs) for related data (language, category, etc.) which can be stored in separate collections
- Image fields are stored as strings (typically URLs or Cloud Storage references)
- The enums can be expanded with additional values as needed
- The model assumes related data (languages, categories) are stored in separate collections
To use this with Firestore, you would:
- Create a 'projects' collection
- Store instances using the toFirestore() method
- Retrieve instances using the fromFirestore() factory
You might want to adjust the Status enum values and add any additional fields specific to your use case. Let me know if you need any modifications or have questions about implementation!
Titles
Each time a user accesses the project in another langate we will use AI to translate it and save what AI returns, herer we will same the title in many langages (this could also be an array if there is no limits on arrays)
- Structure
- title
-
- title #1
-
-
- lanage (english)
-
-
-
- title (text)
-
-
-
- primary (true, false)
-
Permissions / Access
- permissions
-
- access1
-
-
- access_type (private link, public link, inhareted, direct invite)
-
-
-
- channel/clt_acct id
-
-
-
- access level
-
-
-
- expiration (never, date)
-
-
-
- inhareted (id)
-
-
-
- log (id)
-
Collaborators
- collaboration
-
- collab 1
-
-
- role (host, label, producer, author, etc.)
-
-
-
- channel_id
-
-
-
- account id
-
-
-
- royalties %
-
-
-
- Payout account id
-
-
-
- agreed/accepted (true, false)
-
-
-
- log (id)
-
Assets
- asset/project
-
- asset #1
-
-
- asset_type: (audio, vedio, text, list, album, podcast, etc.)
-
-
-
- langage: (english),
-
-
-
- primary (true, false)
-
-
-
- asset_id: (id)
-
-
-
- start (timestamp)
-
-
-
- end (timestamp)
-
-
-
- resolution
-
Metadata
- metadata
-
-
- content_size` ,
-
-
-
- content_duration` ,
-
-
-
- total_view
-
-
-
- total_like`
-
-
-
- total_dislike`
-
-
- hashtags
-
-
- hashtag_id
-
Log
- log
-
- log1
-
-
- type (created, edit, status change, delete, etc)
-
-
-
- time stamp
-
-
-
- by (users ID)
-
-
-
- user log id
-
Sales methods
- sales_methods
-
- method 1
-
-
- cost type (rent, purchase, membership, ads)
-
-
-
- rent (true, false)
-
-
-
- price
-
-
-
- duration (x days, weeks, months)
-
-
-
- sub id (API ID)
-
Revenue
keep track of how much this project is earing (only a summary of earnings data)
awards
list awards won or nominated
charts
keep a list of charts this project is on
events
keep a list of festivals, live performances, movie premers etc