Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

EC-002: Working on data layer schema updates #6

Merged
merged 12 commits into from
Feb 10, 2024
3 changes: 2 additions & 1 deletion .eslintignore
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,5 @@
# temporary
system/
components/
nsx/
nsx/
mock/
12 changes: 10 additions & 2 deletions lib/actions/actions-init.tsx
Original file line number Diff line number Diff line change
@@ -1,14 +1,22 @@
// actions-init.tsx
/* eslint-disable react-hooks/exhaustive-deps, react-hooks/rules-of-hooks */
'use client';
import type { ISupportedContexts, IActionBack, IAction, IStatus, ICreateAction, IDispatch, IPayload } from '@types';
import type {
ISupportedContexts,
IActionBack,
IActionDispatch,
IStatus,
ICreateAction,
IDispatch,
IPayload,
} from '@types';

import { createLogMessage, fluxLog as log } from '@log';
import { useState, useEffect, useContext, useRef } from 'react';

export const CreateAction: ICreateAction =
({ action, type, verb, context }: IActionBack) =>
({ cb }: IAction) => {
({ cb }: IActionDispatch) => {
// eslint-disable-next-line @typescript-eslint/no-unused-vars
const noop: IDispatch = async (...payload: IPayload): Promise<void> => {};

Expand Down
2 changes: 1 addition & 1 deletion lib/actions/db-users-actions.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import { AuthContext } from '@state';
/* public */
export const ALoadUserMeta = BuildAction(CreateAction, {
action: 'hydrate',
type: 'users',
type: 'database',
verb: 'load user meta',
context: AuthContext,
});
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ let usersDatabase = '';
let defaultOrg = '';
let DATABASE_USERS_STRING = '';
let DATABASE_ORGS_STRING = '';
let DEFAULT_ORG = 'demo';
let DEFAULT_ORG = 'community';

/* lean */
if (process.env.NEXUS_MODE !== 'full') {
Expand Down
3 changes: 2 additions & 1 deletion lib/model/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,8 @@ export {
DATABASE_STRING,
DATABASE_USERS_STRING,
DATABASE_ORGS_STRING,
} from './interfaces';
DEFAULT_ORG,
} from './constants';

/* rm-decorators */
export { decorateRMCharacters } from './decorators';
1 change: 0 additions & 1 deletion lib/model/interfaces/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
/* mdb-ifaces */

/* const */
export { DATABASE_STRING, DATABASE_USERS_STRING, DATABASE_ORGS_STRING } from './constants';

// default methods
export { NexusInterface } from './mdb-init-interface';
Expand Down
56 changes: 30 additions & 26 deletions lib/model/interfaces/mdb-init-interface.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,20 +2,15 @@
// mdb-init-interface.ts
import { v4 as uuid } from 'uuid';
import type { UserSchema, INCharacter, UserDecoration, OrgDecoration, ILogger, ILogContext } from '@types';
import { ECollections } from '@constants';
import { default as MongoConnector, _setDb as setDb } from '../mdb-connector';
import {
DATABASE_STRING as databaseName,
DATABASE_USERS_STRING as userDatabaseName,
DATABASE_ORGS_STRING as orgsDatabaseName,
DEFAULT_ORG as defaultOrg,
} from './constants';
import { DEFAULT_ORG as defaultOrg } from '@model';
import { EDBs } from '@constants';

import { patience } from './helpers';

import { dbLog } from '@log';

/* to-do: move types to declaration file */
type Tdbs = 'nexus' | 'organizations' | 'test' | string;

interface IDBGeneric {
[x: string]: {
db: unknown;
Expand Down Expand Up @@ -44,7 +39,7 @@ oplog._.decorateLog = ({ type, action, verb, status, message, priority }) => {
// console.log("@@@ decorating log @@@")
if (!messageState.get) return { type, action, verb, status, message, priority };
const statusMessage: ILogContext = {
type: type || 'mongodb',
type: type || 'database',
action: action || messageState.get().action,
verb: verb || messageState.get().verb,
status: status || messageState.get().status,
Expand Down Expand Up @@ -196,6 +191,15 @@ const _UserSchema: UserDecoration = {
const _OrgSchema: OrgDecoration = {
name: defaultOrg,
members: [],
projects: {
active: [],
inactive: [],
archived: [],
},
services: {
enabled: [],
available: [],
},
rickmorty_meta: {
favorites: {
characters: [] as INCharacter['id'][],
Expand All @@ -205,12 +209,12 @@ const _OrgSchema: OrgDecoration = {

/* private */

const prepare = async (name: Tdbs): Promise<any> => {
async function prepare<DB extends keyof typeof EDBs>(name: (typeof EDBs)[DB]): Promise<any> {
const conn = await MongoConnector;
const db_conn = await setDb(name);
const db = await db_conn.db(name);
return db;
};
}

// IMPORTANT: to-do: to enforce on existing docs (not on insert only)
const createSchemaQuery = () => {
Expand Down Expand Up @@ -247,7 +251,7 @@ const Instance: any = {};
/* private methods */
/* 0. init */
const init = async ({ name }: { name: string }) => {
const usersDb = userDatabaseName || databaseName;
const usersDb = EDBs.USERS || EDBs.DEFAULT;

const _users = {
status: 'loading',
Expand All @@ -259,19 +263,19 @@ const init = async ({ name }: { name: string }) => {
if (process.env.NEXUS_MODE === 'full') {
const _orgs = {
status: 'loading',
db: await prepare(orgsDatabaseName),
db: await prepare(EDBs.ORGS),
};

Instance.orgs = _orgs;
}

Instance.private = {};
Instance.private.loadUsers = async () => {
const users = await Instance.users.db.collection('users');
const users = await Instance.users.db.collection(ECollections.USERS);
return users;
};
Instance.private.reloadUsers = async () => {
const users = await Instance.users.db.collection('users');
const users = await Instance.users.db.collection(ECollections.USERS);
Instance.private.users = users;
return users;
};
Expand All @@ -280,11 +284,11 @@ const init = async ({ name }: { name: string }) => {
/* (PVT) orgs */
if (process.env.NEXUS_MODE === 'full') {
Instance.private.loadOrgs = async () => {
const orgs = await Instance.orgs.db.collection('organizations');
const orgs = await Instance.orgs.db.collection(ECollections.ORGS);
return orgs;
};
Instance.private.reloadOrgs = async () => {
const orgs = await Instance.orgs.db.collection('organizations');
const orgs = await Instance.orgs.db.collection(ECollections.ORGS);
Instance.private.orgs = orgs;
return orgs;
};
Expand All @@ -297,8 +301,8 @@ const init = async ({ name }: { name: string }) => {

Instance.private.defineUserSchema = await defineSchema(
{
db: userDatabaseName || databaseName,
collection: 'users',
db: EDBs.USERS || EDBs.DEFAULT,
collection: ECollections.USERS,
schema: _UserSchema,
docQuery: undefined,
},
Expand All @@ -312,8 +316,8 @@ const init = async ({ name }: { name: string }) => {

const initiator = await defineSchema(
{
db: userDatabaseName || databaseName,
collection: 'users',
db: EDBs.USERS || EDBs.DEFAULT,
collection: ECollections.USERS,
schema: _UserSchema,
docQuery: { email },
},
Expand All @@ -328,8 +332,8 @@ const init = async ({ name }: { name: string }) => {

Instance.private.defineOrgSchema = await defineSchema(
{
db: orgsDatabaseName || databaseName,
collection: 'organizations',
db: EDBs.ORGS || EDBs.DEFAULT,
collection: ECollections.ORGS,
schema: _OrgSchema,
},
Instance.private.orgs,
Expand All @@ -355,8 +359,8 @@ const init = async ({ name }: { name: string }) => {

/* IMPORTANT: to-do: extract method to add to org */
const userQuerySchema = {
db: userDatabaseName || databaseName,
collection: 'users',
db: EDBs.USERS || EDBs.DEFAULT,
collection: ECollections.USERS,
schema: _userQuerySchema,
};

Expand Down
4 changes: 2 additions & 2 deletions lib/model/mdb-connector.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,9 +37,9 @@ const genPromise = (name = '') => {
}

log({
type: 'connector',
type: 'database',
action: 'init',
verb: 'connect',
verb: 'connect to database',
status: 'connecting-to',
message: domain,
});
Expand Down
86 changes: 86 additions & 0 deletions lib/model/schemas/org.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
// org.ts
import type {
NexusActionTypes,
IActionTypes,
IServiceUserAmbiRelation,
IFeatureSet,
OrgDecoration,
INCharacter,
} from '@types';
import { EFeatureStatus, EServiceTypes, EServiceStatus, EServiceNames } from '@constants';
import { DEFAULT_ORG } from '@model';
import { defaultAbilities } from '@schema/user';

interface INexusSet extends Set<IActionTypes> {
gimme?: (value: string) => string[] | [];
}

const publicNexusActions: Set<NexusActionTypes> = new Set(['init', 'login', 'logout', 'hydrate'] as NexusActionTypes[]);
const iterablePublicActions: NexusActionTypes[] = Array.from(publicNexusActions);

const commonActions: INexusSet = new Set<IActionTypes>(['like']);
commonActions.gimme = (value: string) => {
if (commonActions.has(value)) return [value];
return [];
};

export const nominalRMActions = [...iterablePublicActions, commonActions.gimme('like')];

export const defaultRMActions = nominalRMActions.reduce((acc, actionType: IActionTypes) => {
return {
...acc,
[actionType]: true,
};
}, {});

export const defaultRMFeatures: IFeatureSet = {
'love-characters': {
name: 'love-characters',
status: EFeatureStatus.active,
version: '0.0.1',
abilities: defaultAbilities,
},
};

export const RMServiceSchema: IServiceUserAmbiRelation = {
name: EServiceNames.SERV_RM,
type: EServiceTypes.RM,
createdOn: new Date(),
status: EServiceStatus.active,
statusModified: new Date(),
version: '1.0.0',
features: defaultRMFeatures,
};

export const defaultServices = {
[EServiceNames.SERV_RM]: RMServiceSchema,
};

export const defaultProjects = {
[EServiceNames.SERV_RM]: {
name: 'myorg-default-rm-index',
status: 'active',
/*
to-finish: walk the default services
service: defaultServices.get(‘rickmorty’).name,
sid: unknown (NEEDS DEFINE RELATIONS)
*/
},
};
Comment on lines +55 to +69
Copy link
Contributor Author

@angeloreale angeloreale Feb 10, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

let's finish the walk


export const _OrgSchema: OrgDecoration = {
name: DEFAULT_ORG,
members: [],
services: {
enabled: defaultServices,
available: defaultServices,
},
projects: {
active: defaultProjects,
},
rickmorty_meta: {
favorites: {
characters: [] as INCharacter['id'][],
},
},
};
13 changes: 13 additions & 0 deletions lib/model/schemas/relations.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
// relations.ts
import { EUserOrgRoles } from '@constants';
import { defaultAbilities } from '@schema/user';
import { defaultProjects, defaultServices } from '@schema/org';

export const defaultOrgMemberRelation = {
role: [EUserOrgRoles.MEMBER],
abilities: defaultAbilities,
services: defaultServices,
projects: defaultProjects,
org: 'name',
user: 'email',
};
27 changes: 27 additions & 0 deletions lib/model/schemas/user.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
// user.ts
/* schemas */
import type { IFuzzyAbilities, UserDecoration, INCharacter, DUserOrgAmbiRelation } from '@types';
import { EUserOrgRoles, EAbilityStatus } from '@constants';
import { defaultRMActions } from '@schema/org';

/* to finish, use hashmap */
export const defaultAbilities: IFuzzyAbilities = [
{
name: 'like-stuff',
contexts: ['all'],
actions: defaultRMActions,
roles: [EUserOrgRoles.EVERYONE],
restrictions: {},
allowances: {},
status: EAbilityStatus.active,
},
];

export const _UserSchema: UserDecoration = {
rickmorty: {
favorites: {
characters: [] as INCharacter['id'][],
},
},
organizations: [] as DUserOrgAmbiRelation[],
};
Loading
Loading