1e5a22d2f9
Destructive removal per user confirmation ("حذف نهائي ما يرجع").
Removed:
- API: routes/conversations.ts, schema/conversations.ts, all chat
socket handlers in src/index.ts, /admin/users/:id/dependents/
conversations+messages endpoints, conversation/message dependency
counts in users/stats routes.
- Web: pages/chat.tsx, /chat route, dock chat filter, MessageSquare
icon and messages StatCard on home, all chat-related UI in
notifications + admin (dependency badges, delete-dialog rows,
UserDependentConversations/Messages sections, count map keys).
- Locales: nav.chat, home.stats.messages, full chat.* block,
admin.deleteUser conv/msgCount, admin.users.counts.conv/msg,
admin.audit.unit.conversation_*/message_*, admin.dependents.user*.
- OpenAPI spec: tags, all /conversations/* paths, conv/msg dependent
paths, related schemas (ConversationWithDetails, MessageWithSender,
UserDependentConversation/MessageItem+Page, etc.), UserProfile and
UserDeletionConflict conv/msg fields, HomeStats.unreadMessages.
Regenerated client via orval.
- Database: dropped message_reads, messages,
conversation_participants, conversations (CASCADE); deleted
notifications with related_type='conversation' or type='chat';
deleted apps row with slug='chat'; ran drizzle push-force.
- Seed: removed chat:access permission + user-role assignment +
seeded chat app entry from scripts/src/seed.ts.
- Tests: deleted conversations-leave.test.mjs; cleaned chat refs from
list-dependency-counts, delete-force-warnings, audit-log-coverage,
and admin-inline-dependency-counts (e2e) — replaced chat dependents
with note dependents where needed for force-delete coverage.
Notes preserved: notes.tsx noConversationsYet/conversationWith refer
to NOTE THREADS (not chat) and were intentionally NOT touched.
executive-meetings.ts not modified per replit.md restriction.
Pre-existing flaky test failures in executive-meetings/group/etc
suites remain unrelated to this task.
1675 lines
35 KiB
TypeScript
1675 lines
35 KiB
TypeScript
/**
|
|
* Generated by orval v8.5.3 🍺
|
|
* Do not edit manually.
|
|
* Api
|
|
* Tx OS API specification
|
|
* OpenAPI spec version: 0.1.0
|
|
*/
|
|
export interface HealthStatus {
|
|
status: string;
|
|
}
|
|
|
|
export interface ErrorResponse {
|
|
error: string;
|
|
}
|
|
|
|
export interface SuccessResponse {
|
|
success: boolean;
|
|
}
|
|
|
|
export interface RegisterBody {
|
|
username: string;
|
|
email: string;
|
|
password: string;
|
|
/** @nullable */
|
|
displayNameAr?: string | null;
|
|
/** @nullable */
|
|
displayNameEn?: string | null;
|
|
preferredLanguage?: string;
|
|
}
|
|
|
|
export interface CreateUserBody {
|
|
username: string;
|
|
email: string;
|
|
password: string;
|
|
/** @nullable */
|
|
displayNameAr?: string | null;
|
|
/** @nullable */
|
|
displayNameEn?: string | null;
|
|
preferredLanguage?: string;
|
|
/** Initial group memberships in addition to the auto-assigned Everyone group. */
|
|
groupIds?: number[];
|
|
}
|
|
|
|
export interface LoginBody {
|
|
username: string;
|
|
password: string;
|
|
}
|
|
|
|
export interface ForgotPasswordBody {
|
|
/** Username or email */
|
|
identifier: string;
|
|
}
|
|
|
|
export interface ForgotPasswordResponse {
|
|
success: boolean;
|
|
}
|
|
|
|
export interface ResetPasswordBody {
|
|
token: string;
|
|
/** @minLength 6 */
|
|
newPassword: string;
|
|
}
|
|
|
|
export interface VerifyResetTokenBody {
|
|
token: string;
|
|
}
|
|
|
|
export interface AdminResetLinkResponse {
|
|
resetUrl: string;
|
|
expiresAt: string;
|
|
}
|
|
|
|
export interface VerifyResetTokenResponse {
|
|
valid: boolean;
|
|
}
|
|
|
|
export interface UpdateLanguageBody {
|
|
language: string;
|
|
}
|
|
|
|
/**
|
|
* Per-user home-screen clock style preference
|
|
*/
|
|
export type ClockStyle = (typeof ClockStyle)[keyof typeof ClockStyle];
|
|
|
|
export const ClockStyle = {
|
|
full: "full",
|
|
digital: "digital",
|
|
"digital-no-seconds": "digital-no-seconds",
|
|
analog: "analog",
|
|
minimal: "minimal",
|
|
} as const;
|
|
|
|
export interface UpdateClockStyleBody {
|
|
/** Clock style; pass null to clear and use the default */
|
|
clockStyle: ClockStyle | null;
|
|
}
|
|
|
|
export type NotificationSoundId =
|
|
(typeof NotificationSoundId)[keyof typeof NotificationSoundId];
|
|
|
|
export const NotificationSoundId = {
|
|
ding: "ding",
|
|
chime: "chime",
|
|
bell: "bell",
|
|
knock: "knock",
|
|
pop: "pop",
|
|
alert: "alert",
|
|
beep: "beep",
|
|
soft: "soft",
|
|
} as const;
|
|
|
|
export interface UpdateNotificationPreferencesBody {
|
|
notificationSoundOrder?: NotificationSoundId;
|
|
notificationSoundMeeting?: NotificationSoundId;
|
|
notificationSoundNote?: NotificationSoundId;
|
|
notifyOrdersEnabled?: boolean;
|
|
notifyMeetingsEnabled?: boolean;
|
|
notifyNotesEnabled?: boolean;
|
|
vibrationEnabledOrder?: boolean;
|
|
vibrationEnabledMeeting?: boolean;
|
|
vibrationEnabledNote?: boolean;
|
|
notificationsMuted?: boolean;
|
|
}
|
|
|
|
export interface UpdateClockHour12Body {
|
|
/**
|
|
* Whether to use 12-hour (AM/PM) clock format; null clears and uses the default (24-hour)
|
|
* @nullable
|
|
*/
|
|
clockHour12: boolean | null;
|
|
}
|
|
|
|
export interface GroupSummary {
|
|
id: number;
|
|
name: string;
|
|
/** @nullable */
|
|
descriptionAr?: string | null;
|
|
/** @nullable */
|
|
descriptionEn?: string | null;
|
|
}
|
|
|
|
export interface AuthUser {
|
|
id: number;
|
|
username: string;
|
|
email: string;
|
|
/** @nullable */
|
|
displayNameAr?: string | null;
|
|
/** @nullable */
|
|
displayNameEn?: string | null;
|
|
preferredLanguage: string;
|
|
clockStyle?: ClockStyle | null;
|
|
/** @nullable */
|
|
clockHour12?: boolean | null;
|
|
/** @nullable */
|
|
avatarUrl?: string | null;
|
|
isActive: boolean;
|
|
notificationSoundOrder: NotificationSoundId;
|
|
notificationSoundMeeting: NotificationSoundId;
|
|
notificationSoundNote: NotificationSoundId;
|
|
notifyOrdersEnabled: boolean;
|
|
notifyMeetingsEnabled: boolean;
|
|
notifyNotesEnabled: boolean;
|
|
vibrationEnabledOrder: boolean;
|
|
vibrationEnabledMeeting: boolean;
|
|
vibrationEnabledNote: boolean;
|
|
notificationsMuted: boolean;
|
|
roles: string[];
|
|
groups: GroupSummary[];
|
|
createdAt: string;
|
|
}
|
|
|
|
export interface UserProfile {
|
|
id: number;
|
|
username: string;
|
|
email: string;
|
|
/** @nullable */
|
|
displayNameAr?: string | null;
|
|
/** @nullable */
|
|
displayNameEn?: string | null;
|
|
preferredLanguage: string;
|
|
clockStyle?: ClockStyle | null;
|
|
/** @nullable */
|
|
clockHour12?: boolean | null;
|
|
/** @nullable */
|
|
avatarUrl?: string | null;
|
|
isActive: boolean;
|
|
roles: string[];
|
|
groups: GroupSummary[];
|
|
createdAt: string;
|
|
/** Dependent record counts. Populated only by the admin list endpoint
|
|
(GET /users) so the delete dialog can warn before the first click.
|
|
Omitted from single-user responses (GET /users/:id, PATCH, etc).
|
|
*/
|
|
noteCount?: number;
|
|
/** Number of service orders owned by this user. Populated only by the
|
|
admin list endpoint (GET /users).
|
|
*/
|
|
orderCount?: number;
|
|
}
|
|
|
|
export interface UpdateUserBody {
|
|
/** @nullable */
|
|
displayNameAr?: string | null;
|
|
/** @nullable */
|
|
displayNameEn?: string | null;
|
|
isActive?: boolean;
|
|
preferredLanguage?: string;
|
|
/** If provided, replaces the user's group memberships */
|
|
groupIds?: number[];
|
|
}
|
|
|
|
export interface AddUserRoleBody {
|
|
/** @minLength 1 */
|
|
roleName: string;
|
|
}
|
|
|
|
export interface Role {
|
|
id: number;
|
|
name: string;
|
|
/** @nullable */
|
|
descriptionAr?: string | null;
|
|
/** @nullable */
|
|
descriptionEn?: string | null;
|
|
isSystem: boolean;
|
|
createdAt: string;
|
|
/** Number of users assigned this role. Populated only by the admin
|
|
list endpoint (GET /admin/roles) so the admin list can show the
|
|
same dependency counts inline as the Apps/Services/Users/Groups
|
|
panels. Omitted from create/update responses.
|
|
*/
|
|
userCount?: number;
|
|
/** Number of groups granting this role. Populated only by the admin
|
|
list endpoint (GET /admin/roles).
|
|
*/
|
|
groupCount?: number;
|
|
}
|
|
|
|
export interface CreateRoleBody {
|
|
/** @minLength 1 */
|
|
name: string;
|
|
/** @nullable */
|
|
descriptionAr?: string | null;
|
|
/** @nullable */
|
|
descriptionEn?: string | null;
|
|
}
|
|
|
|
export interface UpdateRoleBody {
|
|
/** @minLength 1 */
|
|
name?: string;
|
|
/** @nullable */
|
|
descriptionAr?: string | null;
|
|
/** @nullable */
|
|
descriptionEn?: string | null;
|
|
}
|
|
|
|
export interface RoleUsage {
|
|
userCount: number;
|
|
groupCount: number;
|
|
}
|
|
|
|
export interface RoleDeletionConflict {
|
|
error: string;
|
|
userCount: number;
|
|
groupCount: number;
|
|
}
|
|
|
|
export interface Permission {
|
|
id: number;
|
|
name: string;
|
|
/** @nullable */
|
|
descriptionAr?: string | null;
|
|
/** @nullable */
|
|
descriptionEn?: string | null;
|
|
}
|
|
|
|
export interface AddAppPermissionBody {
|
|
/** ID of the permission to require for this app. */
|
|
permissionId: number;
|
|
}
|
|
|
|
export interface AppPermissionLink {
|
|
appId: number;
|
|
permissionId: number;
|
|
}
|
|
|
|
export interface AppPermissionsImpactBody {
|
|
/** Candidate set of permission IDs that would gate this app. Pass an empty array to model "remove every requirement" (i.e. make the app unrestricted). */
|
|
permissionIds: number[];
|
|
}
|
|
|
|
export interface AppPermissionImpactGroup {
|
|
id: number;
|
|
name: string;
|
|
}
|
|
|
|
export interface AppPermissionsImpact {
|
|
/** Distinct non-admin users who currently see the app and would lose visibility under the candidate permission set. Already accounts for users who keep access via `group_apps` group-grants. */
|
|
affectedUserCount: number;
|
|
/** Distinct non-admin users who currently see the app under the existing permission set. Useful for showing the warning as a fraction (e.g. "12 of 80 will lose access"). */
|
|
currentlyVisibleUserCount: number;
|
|
/** Groups that currently grant this app via `group_apps`. Members of any of these groups keep access regardless of permission changes. */
|
|
groups: AppPermissionImpactGroup[];
|
|
/** True when the candidate set is identical to the current permission set so no change would actually be saved. */
|
|
noChange: boolean;
|
|
}
|
|
|
|
export interface ReplaceRolePermissionsBody {
|
|
/** Full set of permission IDs the role should grant. Existing assignments not present here are removed. */
|
|
permissionIds: number[];
|
|
}
|
|
|
|
export interface RolePermissionsImpactBody {
|
|
/** Candidate set of permission IDs to evaluate against the role's current assignments. */
|
|
permissionIds: number[];
|
|
}
|
|
|
|
export interface RolePermissionImpactGroup {
|
|
id: number;
|
|
name: string;
|
|
}
|
|
|
|
export interface RolePermissionImpactItem {
|
|
permissionId: number;
|
|
permissionName: string;
|
|
/** Distinct users who currently have this permission via this role and would lose it (no other role they hold grants the permission). */
|
|
userCount: number;
|
|
/** Number of groups that currently grant this role. */
|
|
groupCount: number;
|
|
/** Groups that currently grant this role and therefore propagate the removal to their members. */
|
|
groups: RolePermissionImpactGroup[];
|
|
}
|
|
|
|
export interface RolePermissionsImpact {
|
|
/** One entry per permission that is currently assigned to the role but not in the candidate set. */
|
|
removed: RolePermissionImpactItem[];
|
|
/** Distinct users that would lose at least one permission across all removals. */
|
|
totalAffectedUsers: number;
|
|
}
|
|
|
|
export interface Group {
|
|
id: number;
|
|
name: string;
|
|
/** @nullable */
|
|
descriptionAr?: string | null;
|
|
/** @nullable */
|
|
descriptionEn?: string | null;
|
|
isSystem: boolean;
|
|
memberCount: number;
|
|
appCount: number;
|
|
roleCount: number;
|
|
createdAt: string;
|
|
}
|
|
|
|
export interface GroupDeletionConflict {
|
|
error: string;
|
|
memberCount: number;
|
|
appCount: number;
|
|
roleCount: number;
|
|
}
|
|
|
|
export interface UserDeletionConflict {
|
|
error: string;
|
|
noteCount: number;
|
|
orderCount: number;
|
|
}
|
|
|
|
export interface AppDeletionConflict {
|
|
error: string;
|
|
groupCount: number;
|
|
restrictionCount: number;
|
|
openCount: number;
|
|
}
|
|
|
|
export interface ServiceDeletionConflict {
|
|
error: string;
|
|
orderCount: number;
|
|
}
|
|
|
|
export interface GroupDetail {
|
|
id: number;
|
|
name: string;
|
|
/** @nullable */
|
|
descriptionAr?: string | null;
|
|
/** @nullable */
|
|
descriptionEn?: string | null;
|
|
isSystem: boolean;
|
|
appIds: number[];
|
|
roleIds: number[];
|
|
userIds: number[];
|
|
createdAt: string;
|
|
}
|
|
|
|
export interface CreateGroupBody {
|
|
/** @minLength 1 */
|
|
name: string;
|
|
/** @nullable */
|
|
descriptionAr?: string | null;
|
|
/** @nullable */
|
|
descriptionEn?: string | null;
|
|
appIds?: number[];
|
|
roleIds?: number[];
|
|
userIds?: number[];
|
|
}
|
|
|
|
export interface UpdateGroupBody {
|
|
/** @minLength 1 */
|
|
name?: string;
|
|
/** @nullable */
|
|
descriptionAr?: string | null;
|
|
/** @nullable */
|
|
descriptionEn?: string | null;
|
|
appIds?: number[];
|
|
roleIds?: number[];
|
|
userIds?: number[];
|
|
}
|
|
|
|
export interface App {
|
|
id: number;
|
|
slug: string;
|
|
nameAr: string;
|
|
nameEn: string;
|
|
/** @nullable */
|
|
descriptionAr?: string | null;
|
|
/** @nullable */
|
|
descriptionEn?: string | null;
|
|
iconName: string;
|
|
route: string;
|
|
color: string;
|
|
isActive: boolean;
|
|
isSystem: boolean;
|
|
sortOrder: number;
|
|
createdAt: string;
|
|
updatedAt: string;
|
|
/** Number of groups granting access to this app. Populated only by the
|
|
admin list endpoint (GET /admin/apps) so the delete dialog can warn
|
|
before the first click. Omitted from non-admin and single-app
|
|
responses.
|
|
*/
|
|
groupCount?: number;
|
|
/** Number of legacy permission restrictions for this app. Populated
|
|
only by the admin list endpoint (GET /admin/apps).
|
|
*/
|
|
restrictionCount?: number;
|
|
/** Number of recorded app-open events for this app. Populated only by
|
|
the admin list endpoint (GET /admin/apps).
|
|
*/
|
|
openCount?: number;
|
|
}
|
|
|
|
export interface CreateAppBody {
|
|
slug: string;
|
|
nameAr: string;
|
|
nameEn: string;
|
|
/** @nullable */
|
|
descriptionAr?: string | null;
|
|
/** @nullable */
|
|
descriptionEn?: string | null;
|
|
iconName: string;
|
|
route: string;
|
|
color: string;
|
|
isActive?: boolean;
|
|
isSystem?: boolean;
|
|
sortOrder?: number;
|
|
/** Optional set of permission IDs to gate the new app on. Inserted with onConflictDoNothing so duplicates are tolerated. */
|
|
permissionIds?: number[];
|
|
}
|
|
|
|
export interface UpdateAppBody {
|
|
nameAr?: string;
|
|
nameEn?: string;
|
|
/** @nullable */
|
|
descriptionAr?: string | null;
|
|
/** @nullable */
|
|
descriptionEn?: string | null;
|
|
iconName?: string;
|
|
route?: string;
|
|
color?: string;
|
|
isActive?: boolean;
|
|
sortOrder?: number;
|
|
}
|
|
|
|
export interface Service {
|
|
id: number;
|
|
/** @nullable */
|
|
categoryId?: number | null;
|
|
nameAr: string;
|
|
nameEn: string;
|
|
/** @nullable */
|
|
descriptionAr?: string | null;
|
|
/** @nullable */
|
|
descriptionEn?: string | null;
|
|
/** @nullable */
|
|
imageUrl?: string | null;
|
|
/** @nullable */
|
|
price?: string | null;
|
|
isAvailable: boolean;
|
|
sortOrder: number;
|
|
createdAt: string;
|
|
updatedAt: string;
|
|
/** Number of service_orders rows referencing this service. Populated
|
|
only by the list endpoint (GET /services) so the admin delete
|
|
dialog can warn before the first click. Omitted from single-service
|
|
responses.
|
|
*/
|
|
orderCount?: number;
|
|
}
|
|
|
|
export interface CreateServiceBody {
|
|
/** @nullable */
|
|
categoryId?: number | null;
|
|
nameAr: string;
|
|
nameEn: string;
|
|
/** @nullable */
|
|
descriptionAr?: string | null;
|
|
/** @nullable */
|
|
descriptionEn?: string | null;
|
|
/** @nullable */
|
|
imageUrl?: string | null;
|
|
/** @nullable */
|
|
price?: string | null;
|
|
isAvailable?: boolean;
|
|
sortOrder?: number;
|
|
}
|
|
|
|
export interface UpdateServiceBody {
|
|
/** @nullable */
|
|
categoryId?: number | null;
|
|
nameAr?: string;
|
|
nameEn?: string;
|
|
/** @nullable */
|
|
descriptionAr?: string | null;
|
|
/** @nullable */
|
|
descriptionEn?: string | null;
|
|
/** @nullable */
|
|
imageUrl?: string | null;
|
|
/** @nullable */
|
|
price?: string | null;
|
|
isAvailable?: boolean;
|
|
sortOrder?: number;
|
|
}
|
|
|
|
export interface ServiceCategory {
|
|
id: number;
|
|
nameAr: string;
|
|
nameEn: string;
|
|
sortOrder: number;
|
|
createdAt: string;
|
|
}
|
|
|
|
export interface ServiceOrderUser {
|
|
id: number;
|
|
username: string;
|
|
/** @nullable */
|
|
displayNameAr?: string | null;
|
|
/** @nullable */
|
|
displayNameEn?: string | null;
|
|
/** @nullable */
|
|
avatarUrl?: string | null;
|
|
}
|
|
|
|
export interface ServiceOrderService {
|
|
id: number;
|
|
nameAr: string;
|
|
nameEn: string;
|
|
/** @nullable */
|
|
imageUrl?: string | null;
|
|
}
|
|
|
|
export type ServiceOrderStatus =
|
|
(typeof ServiceOrderStatus)[keyof typeof ServiceOrderStatus];
|
|
|
|
export const ServiceOrderStatus = {
|
|
pending: "pending",
|
|
received: "received",
|
|
preparing: "preparing",
|
|
completed: "completed",
|
|
cancelled: "cancelled",
|
|
} as const;
|
|
|
|
export interface ServiceOrder {
|
|
id: number;
|
|
serviceId: number;
|
|
userId: number;
|
|
/** @nullable */
|
|
assignedTo?: number | null;
|
|
/** @nullable */
|
|
notes?: string | null;
|
|
status: ServiceOrderStatus;
|
|
createdAt: string;
|
|
updatedAt: string;
|
|
service: ServiceOrderService;
|
|
requester?: ServiceOrderUser | null;
|
|
assignee?: ServiceOrderUser | null;
|
|
}
|
|
|
|
export interface CreateServiceOrderBody {
|
|
serviceId: number;
|
|
/**
|
|
* @maxLength 500
|
|
* @nullable
|
|
*/
|
|
notes?: string | null;
|
|
}
|
|
|
|
export type UpdateServiceOrderStatusBodyStatus =
|
|
(typeof UpdateServiceOrderStatusBodyStatus)[keyof typeof UpdateServiceOrderStatusBodyStatus];
|
|
|
|
export const UpdateServiceOrderStatusBodyStatus = {
|
|
pending: "pending",
|
|
received: "received",
|
|
preparing: "preparing",
|
|
completed: "completed",
|
|
cancelled: "cancelled",
|
|
} as const;
|
|
|
|
export interface UpdateServiceOrderStatusBody {
|
|
status: UpdateServiceOrderStatusBodyStatus;
|
|
}
|
|
|
|
export interface BulkDeleteServiceOrdersBody {
|
|
/**
|
|
* @minItems 1
|
|
* @maxItems 200
|
|
*/
|
|
ids: number[];
|
|
}
|
|
|
|
export interface BulkDeleteServiceOrdersResponse {
|
|
/** Ids that were successfully deleted. */
|
|
deletedIds: number[];
|
|
/** Ids that were skipped (not found, or caller is not authorized). */
|
|
failedIds: number[];
|
|
}
|
|
|
|
export interface Notification {
|
|
id: number;
|
|
userId: number;
|
|
titleAr: string;
|
|
titleEn: string;
|
|
/** @nullable */
|
|
bodyAr?: string | null;
|
|
/** @nullable */
|
|
bodyEn?: string | null;
|
|
type: string;
|
|
isRead: boolean;
|
|
/** @nullable */
|
|
relatedId?: number | null;
|
|
/** @nullable */
|
|
relatedType?: string | null;
|
|
createdAt: string;
|
|
}
|
|
|
|
export interface AppSettings {
|
|
siteNameAr: string;
|
|
siteNameEn: string;
|
|
registrationOpen: boolean;
|
|
footerTextAr: string;
|
|
footerTextEn: string;
|
|
updatedAt?: string;
|
|
}
|
|
|
|
export interface UpdateMyAppOrderBody {
|
|
/** App IDs in the desired display order */
|
|
order: number[];
|
|
}
|
|
|
|
export interface UpdateAppSettingsBody {
|
|
/**
|
|
* @minLength 1
|
|
* @maxLength 200
|
|
*/
|
|
siteNameAr?: string;
|
|
/**
|
|
* @minLength 1
|
|
* @maxLength 200
|
|
*/
|
|
siteNameEn?: string;
|
|
registrationOpen?: boolean;
|
|
/**
|
|
* @minLength 1
|
|
* @maxLength 300
|
|
*/
|
|
footerTextAr?: string;
|
|
/**
|
|
* @minLength 1
|
|
* @maxLength 300
|
|
*/
|
|
footerTextEn?: string;
|
|
}
|
|
|
|
export interface RequestUploadUrlBody {
|
|
/** @minLength 1 */
|
|
name: string;
|
|
/** @minimum 1 */
|
|
size: number;
|
|
/** @minLength 1 */
|
|
contentType: string;
|
|
}
|
|
|
|
export interface RequestUploadUrlResponse {
|
|
uploadURL: string;
|
|
objectPath: string;
|
|
metadata?: RequestUploadUrlBody;
|
|
}
|
|
|
|
export interface HomeStats {
|
|
totalApps: number;
|
|
totalServices: number;
|
|
unreadNotifications: number;
|
|
totalUsers: number;
|
|
}
|
|
|
|
export type AdminStatsRange =
|
|
(typeof AdminStatsRange)[keyof typeof AdminStatsRange];
|
|
|
|
export const AdminStatsRange = {
|
|
"7d": "7d",
|
|
"30d": "30d",
|
|
"90d": "90d",
|
|
custom: "custom",
|
|
} as const;
|
|
|
|
export type AdminStatsSignupsByDayItem = {
|
|
date: string;
|
|
count: number;
|
|
};
|
|
|
|
export type AdminStatsAppOpensByDayItem = {
|
|
date: string;
|
|
count: number;
|
|
};
|
|
|
|
export type AdminStatsServicesCreatedByDayItem = {
|
|
date: string;
|
|
count: number;
|
|
};
|
|
|
|
export interface TopAppItem {
|
|
appId: number;
|
|
slug: string;
|
|
nameAr: string;
|
|
nameEn: string;
|
|
iconName: string;
|
|
color: string;
|
|
count: number;
|
|
}
|
|
|
|
export interface TopUserItem {
|
|
userId: number;
|
|
username: string;
|
|
/** @nullable */
|
|
displayNameAr?: string | null;
|
|
/** @nullable */
|
|
displayNameEn?: string | null;
|
|
/** @nullable */
|
|
avatarUrl?: string | null;
|
|
count: number;
|
|
}
|
|
|
|
export interface AdminStats {
|
|
range: AdminStatsRange;
|
|
rangeDays: number;
|
|
/** Start date (YYYY-MM-DD UTC) of the selected window */
|
|
rangeFrom?: string;
|
|
/** End date (YYYY-MM-DD UTC) of the selected window */
|
|
rangeTo?: string;
|
|
newUsersInRange: number;
|
|
newUsersPrevRange: number;
|
|
activeServices: number;
|
|
inactiveServices: number;
|
|
signupsByDay: AdminStatsSignupsByDayItem[];
|
|
appOpensByDay: AdminStatsAppOpensByDayItem[];
|
|
appOpensInRange: number;
|
|
appOpensPrevRange: number;
|
|
servicesCreatedByDay: AdminStatsServicesCreatedByDayItem[];
|
|
servicesCreatedInRange: number;
|
|
topApps: TopAppItem[];
|
|
mostActiveUsers: TopUserItem[];
|
|
}
|
|
|
|
export interface AppOpenByAppEntry {
|
|
id: number;
|
|
createdAt: string;
|
|
userId: number;
|
|
username: string;
|
|
/** @nullable */
|
|
displayNameAr?: string | null;
|
|
/** @nullable */
|
|
displayNameEn?: string | null;
|
|
/** @nullable */
|
|
avatarUrl?: string | null;
|
|
}
|
|
|
|
export type AdminAppOpensByAppRange =
|
|
(typeof AdminAppOpensByAppRange)[keyof typeof AdminAppOpensByAppRange];
|
|
|
|
export const AdminAppOpensByAppRange = {
|
|
"7d": "7d",
|
|
"30d": "30d",
|
|
"90d": "90d",
|
|
custom: "custom",
|
|
} as const;
|
|
|
|
export interface AdminAppOpensByApp {
|
|
appId: number;
|
|
slug: string;
|
|
nameAr: string;
|
|
nameEn: string;
|
|
iconName: string;
|
|
color: string;
|
|
range: AdminAppOpensByAppRange;
|
|
rangeDays: number;
|
|
rangeFrom: string;
|
|
rangeTo: string;
|
|
totalCount: number;
|
|
limit: number;
|
|
offset: number;
|
|
/** @nullable */
|
|
nextOffset: number | null;
|
|
opens: AppOpenByAppEntry[];
|
|
}
|
|
|
|
export interface AppOpenByUserEntry {
|
|
id: number;
|
|
createdAt: string;
|
|
appId: number;
|
|
slug: string;
|
|
nameAr: string;
|
|
nameEn: string;
|
|
iconName: string;
|
|
color: string;
|
|
}
|
|
|
|
export type AdminAppOpensByUserRange =
|
|
(typeof AdminAppOpensByUserRange)[keyof typeof AdminAppOpensByUserRange];
|
|
|
|
export const AdminAppOpensByUserRange = {
|
|
"7d": "7d",
|
|
"30d": "30d",
|
|
"90d": "90d",
|
|
custom: "custom",
|
|
} as const;
|
|
|
|
export interface AdminAppOpensByUser {
|
|
userId: number;
|
|
username: string;
|
|
/** @nullable */
|
|
displayNameAr?: string | null;
|
|
/** @nullable */
|
|
displayNameEn?: string | null;
|
|
/** @nullable */
|
|
avatarUrl?: string | null;
|
|
range: AdminAppOpensByUserRange;
|
|
rangeDays: number;
|
|
rangeFrom: string;
|
|
rangeTo: string;
|
|
totalCount: number;
|
|
limit: number;
|
|
offset: number;
|
|
/** @nullable */
|
|
nextOffset: number | null;
|
|
opens: AppOpenByUserEntry[];
|
|
}
|
|
|
|
export interface AppDependentGroupItem {
|
|
id: number;
|
|
name: string;
|
|
/** @nullable */
|
|
descriptionAr: string | null;
|
|
/** @nullable */
|
|
descriptionEn: string | null;
|
|
}
|
|
|
|
export interface AppDependentGroupsPage {
|
|
items: AppDependentGroupItem[];
|
|
totalCount: number;
|
|
limit: number;
|
|
offset: number;
|
|
/** @nullable */
|
|
nextOffset: number | null;
|
|
}
|
|
|
|
export interface AppDependentRestrictionItem {
|
|
id: number;
|
|
name: string;
|
|
/** @nullable */
|
|
descriptionAr: string | null;
|
|
/** @nullable */
|
|
descriptionEn: string | null;
|
|
/** Names of roles currently holding this permission. */
|
|
roles: string[];
|
|
}
|
|
|
|
export interface AppDependentRestrictionsPage {
|
|
items: AppDependentRestrictionItem[];
|
|
totalCount: number;
|
|
limit: number;
|
|
offset: number;
|
|
/** @nullable */
|
|
nextOffset: number | null;
|
|
}
|
|
|
|
export interface AppDependentOpenItem {
|
|
id: number;
|
|
createdAt: string;
|
|
userId: number;
|
|
username: string;
|
|
/** @nullable */
|
|
displayNameAr: string | null;
|
|
/** @nullable */
|
|
displayNameEn: string | null;
|
|
/** @nullable */
|
|
avatarUrl: string | null;
|
|
}
|
|
|
|
export interface AppDependentOpensPage {
|
|
items: AppDependentOpenItem[];
|
|
totalCount: number;
|
|
limit: number;
|
|
offset: number;
|
|
/** @nullable */
|
|
nextOffset: number | null;
|
|
}
|
|
|
|
export interface ServiceDependentOrderItem {
|
|
id: number;
|
|
status: string;
|
|
/** @nullable */
|
|
notes: string | null;
|
|
createdAt: string;
|
|
userId: number;
|
|
username: string;
|
|
/** @nullable */
|
|
displayNameAr: string | null;
|
|
/** @nullable */
|
|
displayNameEn: string | null;
|
|
}
|
|
|
|
export interface ServiceDependentOrdersPage {
|
|
items: ServiceDependentOrderItem[];
|
|
totalCount: number;
|
|
limit: number;
|
|
offset: number;
|
|
/** @nullable */
|
|
nextOffset: number | null;
|
|
}
|
|
|
|
export interface UserDependentNoteItem {
|
|
id: number;
|
|
title: string;
|
|
isPinned: boolean;
|
|
isArchived: boolean;
|
|
updatedAt: string;
|
|
}
|
|
|
|
export type NoteRecipientStatus =
|
|
(typeof NoteRecipientStatus)[keyof typeof NoteRecipientStatus];
|
|
|
|
export const NoteRecipientStatus = {
|
|
unread: "unread",
|
|
read: "read",
|
|
replied: "replied",
|
|
archived: "archived",
|
|
} as const;
|
|
|
|
export interface NoteUserSummary {
|
|
id: number;
|
|
username: string;
|
|
/** @nullable */
|
|
displayNameAr: string | null;
|
|
/** @nullable */
|
|
displayNameEn: string | null;
|
|
/** @nullable */
|
|
avatarUrl?: string | null;
|
|
isActive?: boolean;
|
|
}
|
|
|
|
export interface NoteRecipientSummary {
|
|
id: number;
|
|
noteId?: number;
|
|
recipientUserId: number;
|
|
status: NoteRecipientStatus;
|
|
sentAt: string;
|
|
/** @nullable */
|
|
readAt: string | null;
|
|
/** @nullable */
|
|
archivedAt: string | null;
|
|
recipient?: NoteUserSummary | null;
|
|
}
|
|
|
|
/**
|
|
* A note owned by the caller (My Notes / Archive view).
|
|
*/
|
|
export interface MyNote {
|
|
id: number;
|
|
userId: number;
|
|
title: string;
|
|
content: string;
|
|
color: string;
|
|
isPinned: boolean;
|
|
isArchived: boolean;
|
|
/**
|
|
* Owning folder id, or null for Unfiled.
|
|
* @nullable
|
|
*/
|
|
folderId: number | null;
|
|
createdAt: string;
|
|
updatedAt: string;
|
|
labelIds: number[];
|
|
}
|
|
|
|
export interface NoteFolder {
|
|
id: number;
|
|
userId: number;
|
|
name: string;
|
|
createdAt: string;
|
|
updatedAt: string;
|
|
/** Number of notes in this folder, scoped to the requested tab (active vs archived). */
|
|
noteCount: number;
|
|
}
|
|
|
|
export interface SentNote {
|
|
id: number;
|
|
userId: number;
|
|
title: string;
|
|
content: string;
|
|
color: string;
|
|
isPinned?: boolean;
|
|
isArchived?: boolean;
|
|
/**
|
|
* Owning folder id, or null for Unfiled.
|
|
* @nullable
|
|
*/
|
|
folderId?: number | null;
|
|
createdAt: string;
|
|
updatedAt: string;
|
|
recipients: NoteRecipientSummary[];
|
|
replyCount: number;
|
|
}
|
|
|
|
export interface ReceivedNote {
|
|
id: number;
|
|
title: string;
|
|
content: string;
|
|
color: string;
|
|
/**
|
|
* Owning folder id on the recipient's side, or null for Unfiled.
|
|
* @nullable
|
|
*/
|
|
folderId?: number | null;
|
|
createdAt: string;
|
|
updatedAt: string;
|
|
sender?: NoteUserSummary | null;
|
|
recipientRowId: number;
|
|
status: NoteRecipientStatus;
|
|
sentAt: string;
|
|
/** @nullable */
|
|
readAt: string | null;
|
|
/** @nullable */
|
|
archivedAt: string | null;
|
|
}
|
|
|
|
export interface NoteReply {
|
|
id: number;
|
|
noteId: number;
|
|
senderUserId: number;
|
|
recipientUserId: number;
|
|
content: string;
|
|
createdAt: string;
|
|
sender?: NoteUserSummary | null;
|
|
}
|
|
|
|
export interface NoteThread {
|
|
id: number;
|
|
title: string;
|
|
content: string;
|
|
color: string;
|
|
/** @nullable */
|
|
createdAt?: string | null;
|
|
/** @nullable */
|
|
updatedAt?: string | null;
|
|
senderUserId: number;
|
|
sender?: NoteUserSummary | null;
|
|
isOwner: boolean;
|
|
isAdmin: boolean;
|
|
myStatus: NoteRecipientStatus | null;
|
|
recipients: NoteRecipientSummary[];
|
|
replies: NoteReply[];
|
|
}
|
|
|
|
export interface SendNoteResult {
|
|
success: boolean;
|
|
sent: number;
|
|
}
|
|
|
|
export interface UserDependentNotesPage {
|
|
items: UserDependentNoteItem[];
|
|
totalCount: number;
|
|
limit: number;
|
|
offset: number;
|
|
/** @nullable */
|
|
nextOffset: number | null;
|
|
}
|
|
|
|
export interface UserDependentOrderItem {
|
|
id: number;
|
|
status: string;
|
|
/** @nullable */
|
|
notes: string | null;
|
|
createdAt: string;
|
|
serviceId: number;
|
|
serviceNameAr: string;
|
|
serviceNameEn: string;
|
|
}
|
|
|
|
export interface UserDependentOrdersPage {
|
|
items: UserDependentOrderItem[];
|
|
totalCount: number;
|
|
limit: number;
|
|
offset: number;
|
|
/** @nullable */
|
|
nextOffset: number | null;
|
|
}
|
|
|
|
export interface AuditLogActor {
|
|
id: number;
|
|
username: string;
|
|
/** @nullable */
|
|
displayNameAr?: string | null;
|
|
/** @nullable */
|
|
displayNameEn?: string | null;
|
|
/** @nullable */
|
|
avatarUrl?: string | null;
|
|
}
|
|
|
|
export interface RolePermissionAuditEntry {
|
|
id: number;
|
|
roleId: number;
|
|
previousPermissionIds: number[];
|
|
newPermissionIds: number[];
|
|
addedPermissionIds: number[];
|
|
removedPermissionIds: number[];
|
|
createdAt: string;
|
|
actor: AuditLogActor | null;
|
|
}
|
|
|
|
export interface RolePermissionAuditList {
|
|
entries: RolePermissionAuditEntry[];
|
|
totalCount: number;
|
|
limit: number;
|
|
offset: number;
|
|
/** @nullable */
|
|
nextOffset: number | null;
|
|
}
|
|
|
|
export type PermissionAuditEntryTargetKind =
|
|
(typeof PermissionAuditEntryTargetKind)[keyof typeof PermissionAuditEntryTargetKind];
|
|
|
|
export const PermissionAuditEntryTargetKind = {
|
|
user: "user",
|
|
group: "group",
|
|
app: "app",
|
|
} as const;
|
|
|
|
export type PermissionAuditEntryChangeKind =
|
|
(typeof PermissionAuditEntryChangeKind)[keyof typeof PermissionAuditEntryChangeKind];
|
|
|
|
export const PermissionAuditEntryChangeKind = {
|
|
userroles: "user.roles",
|
|
usergroups: "user.groups",
|
|
groupusers: "group.users",
|
|
grouproles: "group.roles",
|
|
groupapps: "group.apps",
|
|
apppermissions: "app.permissions",
|
|
} as const;
|
|
|
|
export interface PermissionAuditEntry {
|
|
id: number;
|
|
targetKind: PermissionAuditEntryTargetKind;
|
|
targetId: number;
|
|
changeKind: PermissionAuditEntryChangeKind;
|
|
previousIds: number[];
|
|
newIds: number[];
|
|
addedIds: number[];
|
|
removedIds: number[];
|
|
createdAt: string;
|
|
actor: AuditLogActor | null;
|
|
}
|
|
|
|
export interface PermissionAuditList {
|
|
entries: PermissionAuditEntry[];
|
|
totalCount: number;
|
|
limit: number;
|
|
offset: number;
|
|
/** @nullable */
|
|
nextOffset: number | null;
|
|
}
|
|
|
|
/**
|
|
* @nullable
|
|
*/
|
|
export type AuditLogEntryMetadata = { [key: string]: unknown } | null;
|
|
|
|
export interface AuditLogEntry {
|
|
id: number;
|
|
action: string;
|
|
targetType: string;
|
|
/** @nullable */
|
|
targetId: number | null;
|
|
/** @nullable */
|
|
metadata: AuditLogEntryMetadata;
|
|
createdAt: string;
|
|
actor: AuditLogActor | null;
|
|
}
|
|
|
|
export interface AuditLogList {
|
|
entries: AuditLogEntry[];
|
|
totalCount: number;
|
|
limit: number;
|
|
offset: number;
|
|
/** @nullable */
|
|
nextOffset: number | null;
|
|
/** All distinct action names present in the audit log (for building filter UI). */
|
|
actions: string[];
|
|
}
|
|
|
|
export type DeleteAppParams = {
|
|
/**
|
|
* Force deletion of an app that has dependent records (records an audit log entry).
|
|
*/
|
|
force?: boolean;
|
|
};
|
|
|
|
export type DeleteServiceParams = {
|
|
/**
|
|
* Force deletion of a service that has existing orders (records an audit log entry).
|
|
*/
|
|
force?: boolean;
|
|
};
|
|
|
|
export type ListUsersParams = {
|
|
/**
|
|
* Free-text search across username, email, and display names
|
|
*/
|
|
q?: string;
|
|
/**
|
|
* Filter to users that belong to the given group
|
|
*/
|
|
groupId?: number;
|
|
/**
|
|
* Filter by active/disabled state
|
|
*/
|
|
status?: ListUsersStatus;
|
|
};
|
|
|
|
export type ListUsersStatus =
|
|
(typeof ListUsersStatus)[keyof typeof ListUsersStatus];
|
|
|
|
export const ListUsersStatus = {
|
|
active: "active",
|
|
disabled: "disabled",
|
|
} as const;
|
|
|
|
export type DeleteUserParams = {
|
|
/**
|
|
* Force deletion of a user that owns dependent records (records an audit log entry).
|
|
*/
|
|
force?: boolean;
|
|
};
|
|
|
|
export type GetRolePermissionAuditParams = {
|
|
/**
|
|
* @minimum 1
|
|
* @maximum 200
|
|
*/
|
|
limit?: number;
|
|
/**
|
|
* @minimum 0
|
|
*/
|
|
offset?: number;
|
|
/**
|
|
* Restrict results to entries authored by the given user. Use
|
|
`0` or omit to return entries from any actor.
|
|
|
|
* @minimum 0
|
|
*/
|
|
actorUserId?: number;
|
|
/**
|
|
* Start date (inclusive, YYYY-MM-DD UTC).
|
|
*/
|
|
from?: string;
|
|
/**
|
|
* End date (inclusive, YYYY-MM-DD UTC).
|
|
*/
|
|
to?: string;
|
|
};
|
|
|
|
export type ExportRolePermissionAuditCsvParams = {
|
|
/**
|
|
* Restrict results to entries authored by the given user. Use
|
|
`0` or omit to return entries from any actor.
|
|
|
|
* @minimum 0
|
|
*/
|
|
actorUserId?: number;
|
|
/**
|
|
* Start date (inclusive, YYYY-MM-DD UTC).
|
|
*/
|
|
from?: string;
|
|
/**
|
|
* End date (inclusive, YYYY-MM-DD UTC).
|
|
*/
|
|
to?: string;
|
|
};
|
|
|
|
export type ListGroupsParams = {
|
|
q?: string;
|
|
};
|
|
|
|
export type DeleteGroupParams = {
|
|
/**
|
|
* Force deletion of a non-empty group (records an audit log entry).
|
|
*/
|
|
force?: boolean;
|
|
};
|
|
|
|
export type GetUserPermissionAuditParams = {
|
|
/**
|
|
* @minimum 1
|
|
* @maximum 200
|
|
*/
|
|
limit?: number;
|
|
/**
|
|
* @minimum 0
|
|
*/
|
|
offset?: number;
|
|
/**
|
|
* @minimum 0
|
|
*/
|
|
actorUserId?: number;
|
|
from?: string;
|
|
to?: string;
|
|
};
|
|
|
|
export type GetGroupPermissionAuditParams = {
|
|
/**
|
|
* @minimum 1
|
|
* @maximum 200
|
|
*/
|
|
limit?: number;
|
|
/**
|
|
* @minimum 0
|
|
*/
|
|
offset?: number;
|
|
/**
|
|
* @minimum 0
|
|
*/
|
|
actorUserId?: number;
|
|
from?: string;
|
|
to?: string;
|
|
};
|
|
|
|
export type GetAppPermissionAuditParams = {
|
|
/**
|
|
* @minimum 1
|
|
* @maximum 200
|
|
*/
|
|
limit?: number;
|
|
/**
|
|
* @minimum 0
|
|
*/
|
|
offset?: number;
|
|
/**
|
|
* @minimum 0
|
|
*/
|
|
actorUserId?: number;
|
|
from?: string;
|
|
to?: string;
|
|
};
|
|
|
|
export type GetAdminStatsParams = {
|
|
/**
|
|
* Time range for trend stats. Use "custom" with from/to.
|
|
*/
|
|
range?: GetAdminStatsRange;
|
|
/**
|
|
* Start date (inclusive, YYYY-MM-DD UTC) when range=custom
|
|
*/
|
|
from?: string;
|
|
/**
|
|
* End date (inclusive, YYYY-MM-DD UTC) when range=custom
|
|
*/
|
|
to?: string;
|
|
};
|
|
|
|
export type GetAdminStatsRange =
|
|
(typeof GetAdminStatsRange)[keyof typeof GetAdminStatsRange];
|
|
|
|
export const GetAdminStatsRange = {
|
|
"7d": "7d",
|
|
"30d": "30d",
|
|
"90d": "90d",
|
|
custom: "custom",
|
|
} as const;
|
|
|
|
export type GetAdminAppOpensByAppParams = {
|
|
range?: GetAdminAppOpensByAppRange;
|
|
from?: string;
|
|
to?: string;
|
|
/**
|
|
* @minimum 1
|
|
* @maximum 200
|
|
*/
|
|
limit?: number;
|
|
/**
|
|
* @minimum 0
|
|
*/
|
|
offset?: number;
|
|
};
|
|
|
|
export type GetAdminAppOpensByAppRange =
|
|
(typeof GetAdminAppOpensByAppRange)[keyof typeof GetAdminAppOpensByAppRange];
|
|
|
|
export const GetAdminAppOpensByAppRange = {
|
|
"7d": "7d",
|
|
"30d": "30d",
|
|
"90d": "90d",
|
|
custom: "custom",
|
|
} as const;
|
|
|
|
export type GetAdminAppOpensByUserParams = {
|
|
range?: GetAdminAppOpensByUserRange;
|
|
from?: string;
|
|
to?: string;
|
|
/**
|
|
* @minimum 1
|
|
* @maximum 200
|
|
*/
|
|
limit?: number;
|
|
/**
|
|
* @minimum 0
|
|
*/
|
|
offset?: number;
|
|
};
|
|
|
|
export type GetAdminAppOpensByUserRange =
|
|
(typeof GetAdminAppOpensByUserRange)[keyof typeof GetAdminAppOpensByUserRange];
|
|
|
|
export const GetAdminAppOpensByUserRange = {
|
|
"7d": "7d",
|
|
"30d": "30d",
|
|
"90d": "90d",
|
|
custom: "custom",
|
|
} as const;
|
|
|
|
export type ListAuditLogsParams = {
|
|
/**
|
|
* Exact action name to filter by (e.g. "group.force_delete").
|
|
*/
|
|
action?: string;
|
|
/**
|
|
* When true, restrict results to forced deletions only — i.e. rows
|
|
with action `group.force_delete`, `user.force_delete`,
|
|
`app.force_delete`, `service.force_delete`, or any
|
|
`group.delete`/`user.delete`/`app.delete` row whose metadata
|
|
contains `force: true`. Overrides the `action` filter when set.
|
|
|
|
*/
|
|
forcedOnly?: boolean;
|
|
/**
|
|
* Start date (inclusive, YYYY-MM-DD UTC).
|
|
*/
|
|
from?: string;
|
|
/**
|
|
* End date (inclusive, YYYY-MM-DD UTC).
|
|
*/
|
|
to?: string;
|
|
/**
|
|
* Restrict results to entries whose `target_type` exactly matches
|
|
(e.g. "group", "app", "role", "user", "service", "settings").
|
|
Combines with `targetId` and the other filters.
|
|
|
|
*/
|
|
targetType?: string;
|
|
/**
|
|
* Restrict results to entries whose `target_id` exactly matches.
|
|
Typically used together with `targetType` to focus on the history
|
|
of a single entity.
|
|
|
|
* @minimum 1
|
|
*/
|
|
targetId?: number;
|
|
/**
|
|
* Restrict results to entries written by a specific acting user
|
|
(matches `actor_user_id`). Combines with the other filters.
|
|
|
|
* @minimum 1
|
|
*/
|
|
actorUserId?: number;
|
|
/**
|
|
* @minimum 1
|
|
* @maximum 200
|
|
*/
|
|
limit?: number;
|
|
/**
|
|
* @minimum 0
|
|
*/
|
|
offset?: number;
|
|
};
|
|
|
|
export type ExportAuditLogsCsvParams = {
|
|
/**
|
|
* Exact action name to filter by (e.g. "group.force_delete").
|
|
*/
|
|
action?: string;
|
|
/**
|
|
* When true, restrict the export to forced deletions only.
|
|
See the list endpoint for the exact set of matching rows.
|
|
Overrides the `action` filter when set.
|
|
|
|
*/
|
|
forcedOnly?: boolean;
|
|
/**
|
|
* Start date (inclusive, YYYY-MM-DD UTC).
|
|
*/
|
|
from?: string;
|
|
/**
|
|
* End date (inclusive, YYYY-MM-DD UTC).
|
|
*/
|
|
to?: string;
|
|
/**
|
|
* Restrict the export to entries whose `target_type` exactly matches.
|
|
Combines with `targetId` and the other filters.
|
|
|
|
*/
|
|
targetType?: string;
|
|
/**
|
|
* Restrict the export to entries whose `target_id` exactly matches.
|
|
|
|
* @minimum 1
|
|
*/
|
|
targetId?: number;
|
|
/**
|
|
* Restrict the export to entries written by a specific acting user.
|
|
|
|
* @minimum 1
|
|
*/
|
|
actorUserId?: number;
|
|
};
|
|
|
|
export type GetAdminAppDependentGroupsParams = {
|
|
/**
|
|
* @minimum 1
|
|
* @maximum 200
|
|
*/
|
|
limit?: number;
|
|
/**
|
|
* @minimum 0
|
|
*/
|
|
offset?: number;
|
|
};
|
|
|
|
export type GetAdminAppDependentRestrictionsParams = {
|
|
/**
|
|
* @minimum 1
|
|
* @maximum 200
|
|
*/
|
|
limit?: number;
|
|
/**
|
|
* @minimum 0
|
|
*/
|
|
offset?: number;
|
|
};
|
|
|
|
export type GetAdminAppDependentOpensParams = {
|
|
/**
|
|
* @minimum 1
|
|
* @maximum 200
|
|
*/
|
|
limit?: number;
|
|
/**
|
|
* @minimum 0
|
|
*/
|
|
offset?: number;
|
|
};
|
|
|
|
export type GetAdminServiceDependentOrdersParams = {
|
|
/**
|
|
* @minimum 1
|
|
* @maximum 200
|
|
*/
|
|
limit?: number;
|
|
/**
|
|
* @minimum 0
|
|
*/
|
|
offset?: number;
|
|
};
|
|
|
|
export type ListMyNotesAliasParams = {
|
|
archived?: boolean;
|
|
};
|
|
|
|
export type ListReceivedNotesParams = {
|
|
archived?: boolean;
|
|
};
|
|
|
|
export type SendNoteBody = {
|
|
recipientUserIds: number[];
|
|
};
|
|
|
|
export type ArchiveReceivedNoteBody = {
|
|
archived: boolean;
|
|
};
|
|
|
|
export type ReplyToNoteBody = {
|
|
content: string;
|
|
/** Required when the note owner replies and there is more than one recipient. */
|
|
recipientUserId?: number;
|
|
};
|
|
|
|
export type ListNoteFoldersParams = {
|
|
/**
|
|
* Tab scope for noteCount (false = My Notes, true = Archive)
|
|
*/
|
|
archived?: boolean;
|
|
};
|
|
|
|
export type CreateNoteFolderBody = {
|
|
/**
|
|
* @minLength 1
|
|
* @maxLength 80
|
|
*/
|
|
name: string;
|
|
};
|
|
|
|
export type UpdateNoteFolderParams = {
|
|
/**
|
|
* Tab scope for the returned noteCount (false = My Notes, true = Archive)
|
|
*/
|
|
archived?: boolean;
|
|
};
|
|
|
|
export type UpdateNoteFolderBody = {
|
|
/**
|
|
* @minLength 1
|
|
* @maxLength 80
|
|
*/
|
|
name: string;
|
|
};
|
|
|
|
export type GetAdminUserDependentNotesParams = {
|
|
/**
|
|
* @minimum 1
|
|
* @maximum 200
|
|
*/
|
|
limit?: number;
|
|
/**
|
|
* @minimum 0
|
|
*/
|
|
offset?: number;
|
|
};
|
|
|
|
export type GetAdminUserDependentOrdersParams = {
|
|
/**
|
|
* @minimum 1
|
|
* @maximum 200
|
|
*/
|
|
limit?: number;
|
|
/**
|
|
* @minimum 0
|
|
*/
|
|
offset?: number;
|
|
};
|