---
# System prepended metadata

title: PDCEMS - Business API

---

# PDCEMS - Business API

## Enums
```typescript=


export enum UserType {
    CUSTOMER,
    BACK_OFFICE,
}

export enum ContactType {
    PHONE,
    EMAIL,
}

export enum ActionPerformerType {
    SYSTEM,
    USER,
}

export enum ClientType {
    UNCATEGORISED,
    MINISTRY,
    SSIP,
    IP,
    LTD,
}

export enum CategoryType {
    TAB,    // ჩანართი
    FOLDER, // ფოლდერი
}

export enum VerificationType {
    PHONE,
    EMAIL,
    // TODO - more
}
```

## Collections

* dictionaries
* users
* clients
* permissions
* roles
* action-logs
* otp-verifications
* categories - TODO

**embedded fragments**
```typescript=

@Schema({ collection: 'indicators' })
export class Indicator {

    @Prop({ required: true, type: enum })
    public type: IndicatorType; // IMPACT, TASK
    
    @Prop({ required: true, type:  })
    public parent: {
        chapter: ObjectId;
        target: { type: 'ამოცანა ან მიზანი', _id: ObjectId }
    };

    @Prop({ required: true, type: number })
    public no: number;

    @Prop({ required: true })
    public title: I18n;

    @Prop({ required: false })
    public description: I18n;

    @Prop({ required: true, type: TODO })
    public items: { type: ItemType; year: number; value: string; }[];

    public passport: {
        // TODO
        
        // State
        // Requires Approval
    }

    @Prop({ required: true, type: Record })
    public record: Record;
}


@Schema({ collection: 'indicators-passports' })
export class IndicatorPassport {

    @Prop({ required: true, type: enum })
    public type: IndicatorType; // IMPACT, TASK
    
    @Prop({ required: true, type: number })
    public no: number;

    @Prop({ required: true })
    public title: I18n;

    @Prop({ required: false })
    public description: I18n;

    @Prop({ required: true, type: TODO })
    public items: { type: ItemType; year: number; value: string; }[];

    @Prop({ required: true, type: Record })
    public record: Record;
}










export class I18n {
    @Prop({ required: true })
    public ge: string;

    @Prop({ required: false })
    public en: string;
}

export class ActionPerformer {
    @Prop({ required: true, enum: ActionPerformerType })
    public type: ActionPerformerType;

    @Prop({ required: false, type: Types.ObjectId, default: null })
    public user: Types.ObjectId;
}

export class Record {
    @Prop({ required: true, enum: RecordState, default: RecordState.DRAFT })
    public state: RecordState;

    @Prop({ required: true, type: ActionPerformer })
    public author: ActionPerformer;

    @Prop({ required: true, type: Date })
    public createdAt: Date;

    @Prop({ required: false, type: Date })
    public updatedAt: Date;

    @Prop({ required: true, type: Boolean, default: false })
    public deleted: boolean;
}

export class AuthProvider {
    public userId: string;
    public accessToken: string;
    public refreshToken: string;
}

export class AuthProviders {
    public dga: AuthProvider;
    public facebook: AuthProvider;
    public google: AuthProvider;
}

export class Person {

    @Prop({ required: true, unique: true })
    public pid: string;

    @Prop({ required: true })
    public firstName: string;

    @Prop({ required: true })
    public lastName: string;

}

export class ContactItem {
    @Prop({ required: true, unique: true })
    public id: Types.ObjectId;

    @Prop({ required: true, enum: ContactType })
    public type: ContactType;

    @Prop({ required: true })
    public value: string;

    @Prop({ required: true })
    public verified: boolean;
}

export class PrimaryContact {
    public email: ContactItem;
    public phone: ContactItem;
}

export class Contacts {
    @Prop({ type: PrimaryContact })
    public primary: PrimaryContact;

    @Prop({ type: [ContactItem] })
    public contacts: ContactItem[];
}

export class ClientUser {
    @Prop({ required: true, type: Types.ObjectId })
    public user: Types.ObjectId[];

    @Prop({ required: true, type: Types.ObjectId })
    public role: Types.ObjectId[];
}

export class SessionData {
    // TODO - client -> Roles -> Permissions
}
```

**schemas**
```typescript=


@Schema({ collection: 'permissions' })
export class Permission {

    @Prop({ required: false, type: Types.ObjectId })
    public parent: Types.ObjectId;

    @Prop({ required: true, unique: true })
    public keyword: string;

    @Prop({ required: true })
    public title: I18n;
    
    @Prop({ required: false })
    public description: I18n;

    @Prop({ required: true, type: Record })
    public record: Record;
    
}

@Schema({ collection: 'roles' })
export class Role {

    @Prop({ required: true })
    public title: I18n;

    @Prop({ required: false })
    public description: I18n;

    @Prop({ required: true, type: [Types.ObjectId], ref: 'permissions' })
    public permissions: Types.ObjectId[] | Permission[];

    @Prop({ required: true, type: Record })
    public record: Record;
}

@Schema({ collection: 'users' })
export class User {

    @Prop({ required: false, unique: true })
    public username: string;

    @Prop({ required: false })
    public password: string;

    @Prop({ required: true, type: AuthProviders })
    public authProviders: AuthProviders;

    @Prop({ required: true, enum: UserType })
    public type: UserType;

    @Prop({ required: true, type: Person })
    public person: Person;

    @Prop({ required: true, type: Contacts })
    public contacts: Contacts;

    // ეს შესაცვლელია
    @Prop({ required: true, type: [Types.ObjectId], ref: 'roles' })
    public roles: Role[];

    @Prop({ required: true, type: [Types.ObjectId] })
    public clients: Types.ObjectId[];
    // ------

    @Prop({ required: true, default: false })
    public isRoot: boolean;

    @Prop({ required: true, type: Record })
    public record: Record;
}

@Schema({ collection: 'clients' })
export class Client {

    @Prop({ required: false })
    public parentId: string;

    @Prop({ required: true })
    public title: I18n;

    @Prop({ required: true, enum: ClientType })
    public type: ClientType;

    @Prop({ required: true, type: [Types.ObjectId] })
    public admin: Types.ObjectId[];

    @Prop({ required: true, type: Record })
    public record: Record;

}

@Schema({ collection: 'action-logs' })
export class ActionLog {

    @Prop({ required: true, type: Types.ObjectId })
    public target: Types.ObjectId;

    @Prop({ required: true, type: [String] })
    public group: string[];

    @Prop({ required: true, type: I18n })
    public message: I18n;

    @Prop({ required: false, type: mongoose.Schema.Types.Mixed })
    public before: any;

    @Prop({ required: false, type: mongoose.Schema.Types.Mixed })
    public after: any;

    @Prop({ required: true, type: ActionPerformer })
    public actionPerformer: ActionPerformer;

    @Prop({ required: true, type: Record })
    public record: Record;

}

@Schema({ collection: 'otp-verifications' })
export class OTPVerification {
    @Prop({ required: true, enum: VerificationType })
    public type: VerificationType;

    @Prop({ required: true, type: Types.ObjectId })
    public target: Types.ObjectId;

    @Prop({ required: true })
    public code: string;
    
    @Prop({ required: true, type: Types.ObjectId })
    public user: Types.ObjectId;

    @Prop({ required: true, default: false })
    public used: boolean;

    @Prop({ required: true, type: Date })
    public expiresAt: Date;

    @Prop({ required: true, type: Record })
    public record: Record;
}

@Schema({ collection: 'sessions' })
export class OTPVerification {
    
    @Prop({ required: true, type: Types.ObjectId })
    public user: Types.ObjectId;

    @Prop({ required: true })
    public token: string;

    @Prop({ required: true })
    public userAgent: string;
    
    @Prop({ required: true, type: SessionData })
    public data: SessionData;

    @Prop({ required: true, type: Date })
    public expiresAt: Date;

    @Prop({ required: true, type: Record })
    public record: Record;
}

// ....................................
// TODO ... for pdcems business process
// ....................................

@Schema({ collection: 'categories' })
export class Category {

    @Prop({ required: false, type: Types.ObjectId })
    public parentId: Types.ObjectId;

    @Prop({ required: true })
    public title: I18n;

    @Prop({ required: false })
    public description: I18n;

    // TODO
    // find out details

    @Prop({ required: true, type: Record })
    public record: Record;
}

```

## Gateway API

**Get User Session**
```=
Headers:
    Content-Type: application/json
    Authorization: JWT Token

Method:
    GET {{gateway_api}}/v1.0/sessions
```

**Open User Session**
```=
Headers:
    Content-Type: application/json

Method:
    POST {{gateway_api}}/v1.0/sessions

Body:
    {
        "data": {
            "username": "",
            "password": ""
        }
    }
```

**Delete User Session**
```=
Headers:
    Content-Type: application/json
    Authorization: JWT Token

Method:
    DELETE {{gateway_api}}/v1.0/sessions
```


## Session API
**Get User Session**
```=
Headers:
    Content-Type: application/json
    X-Token: {{USER_JWT_TOKEN}}
    X-User-ID: {{USER_ID}}
    
Method:
    GET {{session_api}}/v1.0/sessions
```

**Open User Session**
```=
Headers:
    Content-Type: application/json

Method:
    POST {{session_api}}/v1.0/sessions

Body:
    {
        "data": {
            "username": "",
            "password": ""
        }
    }
```

**Delete User Session**
```=
Headers:
    Content-Type: application/json
    X-Token: {{USER_JWT_TOKEN}}
    X-User-ID: {{USER_ID}}

Method:
    DELETE {{session_api}}/v1.0/sessions
```