@brimble/models 3.8.14 → 3.8.16

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.ts CHANGED
@@ -58,7 +58,8 @@ export { default as SandboxImage } from "./sandbox-image";
58
58
  export { default as SandboxSnapshot } from "./sandbox-snapshot";
59
59
  export { default as SandboxSnapshotUsageSegment } from "./sandbox-snapshot-usage-segment";
60
60
  export { default as SandboxUsageSegment } from "./sandbox-usage-segment";
61
- export { IUser, IGit, IProject, IProjectAnalytics, IPreview, IProjectConnection, IFollowing, IIntegration, IEnv, IServer, IDomain, IToken, IMember, ITeam, IInstalledIntegration, ILog, ISubscription, ICard, IDns, IRole, IPermission, IMemberPermission, IWallet, IDbImage, IJob, ILicense, IPlanConfiguration, IAutoScalingGroup, IComputeChange, IRegion, IVolume, IFramework, BrimbleFrameworkType, ISettings, ILoadBalancerPort, IDomainRenewal, IDomainTransfer, IWebhookCategory, IWebhookEvent, IWebhookSetting, IIntention, IProvider, ICollabAnnotation, ICollabComment, ICollabAttachment, ICollabIntegration, ICollabSettings, ICollabShareToken, ICollabPushSubscription, IAppMessage, IInvoice, ITag, IProjectTagAssignment, ICashierSubscription, ICashierSubscriptionItem, IProjectEnvironment, IEnvironmentVariable, IActivityLog, IOwnershipTransfer, ISandbox, ISandboxSpecs, ISandboxImage, ISandboxSnapshot, ISandboxSnapshotUsageSegment, ISandboxSnapshotUsageSegmentCosts, ISandboxUsageSegment, ISandboxUsageSegmentCurrent, ISandboxUsageSegmentCosts, } from "./types";
61
+ export { default as VolumeUsageSegment } from "./volume-usage-segment";
62
+ export { IUser, IGit, IProject, IProjectAnalytics, IPreview, IProjectConnection, IFollowing, IIntegration, IEnv, IServer, IDomain, IToken, IMember, ITeam, IInstalledIntegration, ILog, ISubscription, ICard, IDns, IRole, IPermission, IMemberPermission, IWallet, IDbImage, IJob, ILicense, IPlanConfiguration, IAutoScalingGroup, IComputeChange, IRegion, IVolume, IFramework, BrimbleFrameworkType, ISettings, ILoadBalancerPort, IDomainRenewal, IDomainTransfer, IWebhookCategory, IWebhookEvent, IWebhookSetting, IIntention, IProvider, ICollabAnnotation, ICollabComment, ICollabAttachment, ICollabIntegration, ICollabSettings, ICollabShareToken, ICollabPushSubscription, IAppMessage, IInvoice, ITag, IProjectTagAssignment, ICashierSubscription, ICashierSubscriptionItem, IProjectEnvironment, IEnvironmentVariable, IActivityLog, IOwnershipTransfer, ISandbox, ISandboxSpecs, ISandboxImage, ISandboxSnapshot, ISandboxSnapshotUsageSegment, ISandboxSnapshotUsageSegmentCosts, ISandboxUsageSegment, ISandboxUsageSegmentCurrent, ISandboxUsageSegmentCosts, IVolumeUsageSegment, IVolumeUsageSegmentCosts, } from "./types";
62
63
  export { GIT_TYPE, INTEGRATION_TYPES, INTEGRATION_PROVIDERS, OAUTH_PERMISSIONS, ENVIRONMENT, SERVER_STATUS, ROLES, SUBSCRIPTION_PLAN_TYPE, PROJECT_STATUS, SUBSCRIPTION_STATUS, CARD_TYPES, DNS_TYPE, PERMISSION_TYPE, REQUEST_TYPE, ServiceType, DatabaseEngine, JobStatus, LicenseStatus, REGION_CONTINENT, BUILD_DISABLED_BY, SERVER_PROTOCOL, FrameworkApplicationType, DomainRenewalStatus, DomainTransferProvider, DomainTransferDirection, DomainTransferStatus, NomadDeploymentStatus, COLLAB_ANNOTATION_STATUS, COLLAB_INTEGRATION_TYPE, COLLAB_THEME, COLLAB_TOOLBAR_POSITION, INVOICE_STATUS, INVOICE_PAYMENT_STATUS, INVOICE_TYPE, SANDBOX_TEMPLATE, SANDBOX_STATUS, SANDBOX_DESTROY_REASON, SANDBOX_SNAPSHOT_STATUS, } from "./enum";
63
64
  import mongoose from "mongoose";
64
65
  export declare const connectToMongo: (mongoUrl: string, config?: mongoose.ConnectOptions) => Promise<void>;
package/dist/index.js CHANGED
@@ -13,8 +13,8 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
13
13
  };
14
14
  Object.defineProperty(exports, "__esModule", { value: true });
15
15
  exports.ProjectTagAssignment = exports.Tag = exports.Invoice = exports.AppMessage = exports.CollabPushSubscription = exports.CollabShareToken = exports.CollabSettings = exports.CollabIntegration = exports.CollabComment = exports.CollabAnnotation = exports.Provider = exports.Intention = exports.WebhookSetting = exports.WebhookEvent = exports.WebhookCategory = exports.DomainTransfer = exports.DomainRenewal = exports.LoadBalancerPort = exports.Settings = exports.Framework = exports.Volume = exports.Region = exports.ComputeChange = exports.AutoScalingGroup = exports.PlanConfiguration = exports.Liscense = exports.Job = exports.DbImage = exports.Wallet = exports.Server = exports.Card = exports.Subscription = exports.Log = exports.Role = exports.MemberPermission = exports.Permission = exports.Member = exports.Team = exports.Token = exports.Env = exports.Dns = exports.Domain = exports.Integration = exports.Following = exports.ProjectConnection = exports.Preview = exports.ProjectAnalytics = exports.DeletedProject = exports.Project = exports.User = void 0;
16
- exports.connectToMongo = exports.SANDBOX_SNAPSHOT_STATUS = exports.SANDBOX_DESTROY_REASON = exports.SANDBOX_STATUS = exports.SANDBOX_TEMPLATE = exports.INVOICE_TYPE = exports.INVOICE_PAYMENT_STATUS = exports.INVOICE_STATUS = exports.COLLAB_TOOLBAR_POSITION = exports.COLLAB_THEME = exports.COLLAB_INTEGRATION_TYPE = exports.COLLAB_ANNOTATION_STATUS = exports.NomadDeploymentStatus = exports.DomainTransferStatus = exports.DomainTransferDirection = exports.DomainTransferProvider = exports.DomainRenewalStatus = exports.FrameworkApplicationType = exports.SERVER_PROTOCOL = exports.BUILD_DISABLED_BY = exports.REGION_CONTINENT = exports.LicenseStatus = exports.JobStatus = exports.DatabaseEngine = exports.ServiceType = exports.REQUEST_TYPE = exports.PERMISSION_TYPE = exports.DNS_TYPE = exports.CARD_TYPES = exports.SUBSCRIPTION_STATUS = exports.PROJECT_STATUS = exports.SUBSCRIPTION_PLAN_TYPE = exports.ROLES = exports.SERVER_STATUS = exports.ENVIRONMENT = exports.OAUTH_PERMISSIONS = exports.INTEGRATION_PROVIDERS = exports.INTEGRATION_TYPES = exports.GIT_TYPE = exports.SandboxUsageSegment = exports.SandboxSnapshotUsageSegment = exports.SandboxSnapshot = exports.SandboxImage = exports.Sandbox = exports.OwnershipTransfer = exports.ActivityLog = exports.EnvironmentVariable = exports.ProjectEnvironment = exports.CashierSubscriptionItem = exports.CashierSubscription = void 0;
17
- exports.healthCheckMongo = exports.closeMongo = exports.db = void 0;
16
+ exports.SANDBOX_SNAPSHOT_STATUS = exports.SANDBOX_DESTROY_REASON = exports.SANDBOX_STATUS = exports.SANDBOX_TEMPLATE = exports.INVOICE_TYPE = exports.INVOICE_PAYMENT_STATUS = exports.INVOICE_STATUS = exports.COLLAB_TOOLBAR_POSITION = exports.COLLAB_THEME = exports.COLLAB_INTEGRATION_TYPE = exports.COLLAB_ANNOTATION_STATUS = exports.NomadDeploymentStatus = exports.DomainTransferStatus = exports.DomainTransferDirection = exports.DomainTransferProvider = exports.DomainRenewalStatus = exports.FrameworkApplicationType = exports.SERVER_PROTOCOL = exports.BUILD_DISABLED_BY = exports.REGION_CONTINENT = exports.LicenseStatus = exports.JobStatus = exports.DatabaseEngine = exports.ServiceType = exports.REQUEST_TYPE = exports.PERMISSION_TYPE = exports.DNS_TYPE = exports.CARD_TYPES = exports.SUBSCRIPTION_STATUS = exports.PROJECT_STATUS = exports.SUBSCRIPTION_PLAN_TYPE = exports.ROLES = exports.SERVER_STATUS = exports.ENVIRONMENT = exports.OAUTH_PERMISSIONS = exports.INTEGRATION_PROVIDERS = exports.INTEGRATION_TYPES = exports.GIT_TYPE = exports.VolumeUsageSegment = exports.SandboxUsageSegment = exports.SandboxSnapshotUsageSegment = exports.SandboxSnapshot = exports.SandboxImage = exports.Sandbox = exports.OwnershipTransfer = exports.ActivityLog = exports.EnvironmentVariable = exports.ProjectEnvironment = exports.CashierSubscriptionItem = exports.CashierSubscription = void 0;
17
+ exports.healthCheckMongo = exports.closeMongo = exports.db = exports.connectToMongo = void 0;
18
18
  var user_1 = require("./user");
19
19
  Object.defineProperty(exports, "User", { enumerable: true, get: function () { return __importDefault(user_1).default; } });
20
20
  var project_1 = require("./project");
@@ -136,6 +136,8 @@ var sandbox_snapshot_usage_segment_1 = require("./sandbox-snapshot-usage-segment
136
136
  Object.defineProperty(exports, "SandboxSnapshotUsageSegment", { enumerable: true, get: function () { return __importDefault(sandbox_snapshot_usage_segment_1).default; } });
137
137
  var sandbox_usage_segment_1 = require("./sandbox-usage-segment");
138
138
  Object.defineProperty(exports, "SandboxUsageSegment", { enumerable: true, get: function () { return __importDefault(sandbox_usage_segment_1).default; } });
139
+ var volume_usage_segment_1 = require("./volume-usage-segment");
140
+ Object.defineProperty(exports, "VolumeUsageSegment", { enumerable: true, get: function () { return __importDefault(volume_usage_segment_1).default; } });
139
141
  var enum_1 = require("./enum");
140
142
  Object.defineProperty(exports, "GIT_TYPE", { enumerable: true, get: function () { return enum_1.GIT_TYPE; } });
141
143
  Object.defineProperty(exports, "INTEGRATION_TYPES", { enumerable: true, get: function () { return enum_1.INTEGRATION_TYPES; } });
package/dist/sandbox.js CHANGED
@@ -107,6 +107,15 @@ const sandboxSchema = new mongoose_1.Schema({
107
107
  ref: "SandboxSnapshot",
108
108
  default: null,
109
109
  },
110
+ snapshot_mode: {
111
+ type: String,
112
+ enum: ["automatic", "manual"],
113
+ default: "manual",
114
+ },
115
+ snapshot_frequency: {
116
+ type: String,
117
+ default: null,
118
+ },
110
119
  isDeleted: {
111
120
  type: Boolean,
112
121
  default: false,
@@ -59,3 +59,4 @@ export type { ISandboxImage } from "./sandbox-image";
59
59
  export type { ISandboxSnapshot } from "./sandbox-snapshot";
60
60
  export type { ISandboxSnapshotUsageSegment, ISandboxSnapshotUsageSegmentCosts, } from "./sandbox-snapshot-usage-segment";
61
61
  export type { ISandboxUsageSegment, ISandboxUsageSegmentCurrent, ISandboxUsageSegmentCosts, } from "./sandbox-usage-segment";
62
+ export type { IVolumeUsageSegment, IVolumeUsageSegmentCosts, } from "./volume-usage-segment";
@@ -33,5 +33,7 @@ export interface ISandbox extends Document {
33
33
  paused_at: Date | null;
34
34
  image_override: string | null;
35
35
  from_snapshot: Types.ObjectId | null;
36
+ snapshot_mode: "automatic" | "manual";
37
+ snapshot_frequency: string | null;
36
38
  isDeleted: boolean;
37
39
  }
@@ -0,0 +1,16 @@
1
+ import { Document, Types } from "mongoose";
2
+ export interface IVolumeUsageSegmentCosts {
3
+ startDate: Date;
4
+ endDate: Date | null;
5
+ }
6
+ export interface IVolumeUsageSegment extends Document {
7
+ _id: Types.ObjectId;
8
+ volume_id: Types.ObjectId;
9
+ user_id: Types.ObjectId;
10
+ team_id: Types.ObjectId | null;
11
+ size_gb: number;
12
+ costs: IVolumeUsageSegmentCosts;
13
+ billed: boolean;
14
+ createdAt: Date;
15
+ updatedAt: Date;
16
+ }
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -1,14 +1,17 @@
1
- import { Document } from "mongoose";
1
+ import { Document, Types } from "mongoose";
2
2
  import { IUser } from "./user";
3
3
  import { ITeam } from "./team";
4
- import { ISubscription } from "./subscription";
5
4
  export interface IVolume extends Document {
6
5
  name: string;
7
6
  user?: IUser;
8
7
  team?: ITeam;
9
- subscription: ISubscription;
10
8
  size: number;
11
9
  mount_path?: string;
10
+ csi_volume_id: string | null;
11
+ region: string | null;
12
+ attached_sandbox_id: Types.ObjectId | null;
13
+ attached_project_id: Types.ObjectId | null;
14
+ last_attached_at: Date | null;
12
15
  created_at?: Date;
13
16
  updated_at?: Date;
14
17
  }
@@ -0,0 +1,30 @@
1
+ /// <reference types="mongoose/types/aggregate" />
2
+ /// <reference types="mongoose/types/callback" />
3
+ /// <reference types="mongoose/types/collection" />
4
+ /// <reference types="mongoose/types/connection" />
5
+ /// <reference types="mongoose/types/cursor" />
6
+ /// <reference types="mongoose/types/document" />
7
+ /// <reference types="mongoose/types/error" />
8
+ /// <reference types="mongoose/types/expressions" />
9
+ /// <reference types="mongoose/types/helpers" />
10
+ /// <reference types="mongoose/types/middlewares" />
11
+ /// <reference types="mongoose/types/indexes" />
12
+ /// <reference types="mongoose/types/models" />
13
+ /// <reference types="mongoose/types/mongooseoptions" />
14
+ /// <reference types="mongoose/types/pipelinestage" />
15
+ /// <reference types="mongoose/types/populate" />
16
+ /// <reference types="mongoose/types/query" />
17
+ /// <reference types="mongoose/types/schemaoptions" />
18
+ /// <reference types="mongoose/types/schematypes" />
19
+ /// <reference types="mongoose/types/session" />
20
+ /// <reference types="mongoose/types/types" />
21
+ /// <reference types="mongoose/types/utility" />
22
+ /// <reference types="mongoose/types/validation" />
23
+ /// <reference types="mongoose/types/virtuals" />
24
+ /// <reference types="mongoose" />
25
+ /// <reference types="mongoose/types/inferschematype" />
26
+ import { IVolumeUsageSegment } from "./types/volume-usage-segment";
27
+ declare const _default: import("mongoose").Model<IVolumeUsageSegment, {}, {}, {}, import("mongoose").Document<unknown, {}, IVolumeUsageSegment> & IVolumeUsageSegment & Required<{
28
+ _id: import("mongoose").Types.ObjectId;
29
+ }>, any>;
30
+ export default _default;
@@ -0,0 +1,48 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const mongoose_1 = require("mongoose");
4
+ const volumeUsageSegmentSchema = new mongoose_1.Schema({
5
+ volume_id: {
6
+ type: mongoose_1.Schema.Types.ObjectId,
7
+ ref: "Volume",
8
+ required: true,
9
+ },
10
+ user_id: {
11
+ type: mongoose_1.Schema.Types.ObjectId,
12
+ ref: "User",
13
+ required: true,
14
+ index: true,
15
+ },
16
+ team_id: {
17
+ type: mongoose_1.Schema.Types.ObjectId,
18
+ ref: "Team",
19
+ default: null,
20
+ index: true,
21
+ },
22
+ size_gb: {
23
+ type: Number,
24
+ default: 0,
25
+ },
26
+ costs: {
27
+ startDate: { type: Date, required: true },
28
+ endDate: { type: Date, default: null },
29
+ },
30
+ billed: {
31
+ type: Boolean,
32
+ default: false,
33
+ index: true,
34
+ },
35
+ }, {
36
+ timestamps: true,
37
+ });
38
+ volumeUsageSegmentSchema.index({ user_id: 1, billed: 1, "costs.endDate": 1 });
39
+ volumeUsageSegmentSchema.index({ team_id: 1, billed: 1, "costs.endDate": 1 });
40
+ volumeUsageSegmentSchema.index({ volume_id: 1, "costs.endDate": 1 });
41
+ // Partial unique: at most one open (endDate: null) segment per volume.
42
+ // The provider relies on E11000 keyPattern.volume_id to detect race-condition duplicates.
43
+ volumeUsageSegmentSchema.index({ volume_id: 1 }, {
44
+ unique: true,
45
+ partialFilterExpression: { "costs.endDate": null },
46
+ name: "unique_open_segment_per_volume",
47
+ });
48
+ exports.default = (0, mongoose_1.model)("VolumeUsageSegment", volumeUsageSegmentSchema, "volume_usage_segments");
package/dist/volume.js CHANGED
@@ -15,13 +15,21 @@ const volumeSchema = new mongoose_1.Schema({
15
15
  ref: "Team",
16
16
  default: null,
17
17
  },
18
- subscription: {
19
- type: mongoose_1.Schema.Types.ObjectId,
20
- required: true,
21
- ref: "Subscription",
22
- },
23
18
  size: { type: Number, required: true },
24
19
  mount_path: { type: String },
20
+ csi_volume_id: { type: String, default: null },
21
+ region: { type: String, default: null },
22
+ attached_sandbox_id: {
23
+ type: mongoose_1.Schema.Types.ObjectId,
24
+ ref: "Sandbox",
25
+ default: null,
26
+ },
27
+ attached_project_id: {
28
+ type: mongoose_1.Schema.Types.ObjectId,
29
+ ref: "Project",
30
+ default: null,
31
+ },
32
+ last_attached_at: { type: Date, default: null },
25
33
  }, {
26
34
  timestamps: {
27
35
  createdAt: "created_at",
package/index.ts CHANGED
@@ -58,6 +58,7 @@ export { default as SandboxImage } from "./sandbox-image";
58
58
  export { default as SandboxSnapshot } from "./sandbox-snapshot";
59
59
  export { default as SandboxSnapshotUsageSegment } from "./sandbox-snapshot-usage-segment";
60
60
  export { default as SandboxUsageSegment } from "./sandbox-usage-segment";
61
+ export { default as VolumeUsageSegment } from "./volume-usage-segment";
61
62
 
62
63
  export {
63
64
  IUser,
@@ -128,6 +129,8 @@ export {
128
129
  ISandboxUsageSegment,
129
130
  ISandboxUsageSegmentCurrent,
130
131
  ISandboxUsageSegmentCosts,
132
+ IVolumeUsageSegment,
133
+ IVolumeUsageSegmentCosts,
131
134
  } from "./types";
132
135
  export {
133
136
  GIT_TYPE,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@brimble/models",
3
- "version": "3.8.14",
3
+ "version": "3.8.16",
4
4
  "description": "Brimble models",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
package/sandbox.ts CHANGED
@@ -107,6 +107,15 @@ const sandboxSchema: Schema = new Schema({
107
107
  ref: "SandboxSnapshot",
108
108
  default: null,
109
109
  },
110
+ snapshot_mode: {
111
+ type: String,
112
+ enum: ["automatic", "manual"],
113
+ default: "manual",
114
+ },
115
+ snapshot_frequency: {
116
+ type: String,
117
+ default: null,
118
+ },
110
119
  isDeleted: {
111
120
  type: Boolean,
112
121
  default: false,
package/types/index.ts CHANGED
@@ -66,3 +66,7 @@ export type {
66
66
  ISandboxUsageSegmentCurrent,
67
67
  ISandboxUsageSegmentCosts,
68
68
  } from "./sandbox-usage-segment";
69
+ export type {
70
+ IVolumeUsageSegment,
71
+ IVolumeUsageSegmentCosts,
72
+ } from "./volume-usage-segment";
package/types/sandbox.ts CHANGED
@@ -35,5 +35,7 @@ export interface ISandbox extends Document {
35
35
  paused_at: Date | null;
36
36
  image_override: string | null;
37
37
  from_snapshot: Types.ObjectId | null;
38
+ snapshot_mode: "automatic" | "manual";
39
+ snapshot_frequency: string | null;
38
40
  isDeleted: boolean;
39
41
  }
@@ -0,0 +1,18 @@
1
+ import { Document, Types } from "mongoose";
2
+
3
+ export interface IVolumeUsageSegmentCosts {
4
+ startDate: Date;
5
+ endDate: Date | null;
6
+ }
7
+
8
+ export interface IVolumeUsageSegment extends Document {
9
+ _id: Types.ObjectId;
10
+ volume_id: Types.ObjectId;
11
+ user_id: Types.ObjectId;
12
+ team_id: Types.ObjectId | null;
13
+ size_gb: number;
14
+ costs: IVolumeUsageSegmentCosts;
15
+ billed: boolean;
16
+ createdAt: Date;
17
+ updatedAt: Date;
18
+ }
package/types/volume.ts CHANGED
@@ -1,15 +1,18 @@
1
- import { Document } from "mongoose";
1
+ import { Document, Types } from "mongoose";
2
2
  import { IUser } from "./user";
3
3
  import { ITeam } from "./team";
4
- import { ISubscription } from "./subscription";
5
4
 
6
5
  export interface IVolume extends Document {
7
6
  name: string;
8
7
  user?: IUser;
9
8
  team?: ITeam;
10
- subscription: ISubscription;
11
9
  size: number;
12
10
  mount_path?: string;
11
+ csi_volume_id: string | null;
12
+ region: string | null;
13
+ attached_sandbox_id: Types.ObjectId | null;
14
+ attached_project_id: Types.ObjectId | null;
15
+ last_attached_at: Date | null;
13
16
  created_at?: Date;
14
17
  updated_at?: Date;
15
18
  }
@@ -0,0 +1,61 @@
1
+ import { model, Schema } from "mongoose";
2
+ import { IVolumeUsageSegment } from "./types/volume-usage-segment";
3
+
4
+ const volumeUsageSegmentSchema = new Schema<IVolumeUsageSegment>(
5
+ {
6
+ volume_id: {
7
+ type: Schema.Types.ObjectId,
8
+ ref: "Volume",
9
+ required: true,
10
+ },
11
+ user_id: {
12
+ type: Schema.Types.ObjectId,
13
+ ref: "User",
14
+ required: true,
15
+ index: true,
16
+ },
17
+ team_id: {
18
+ type: Schema.Types.ObjectId,
19
+ ref: "Team",
20
+ default: null,
21
+ index: true,
22
+ },
23
+ size_gb: {
24
+ type: Number,
25
+ default: 0,
26
+ },
27
+ costs: {
28
+ startDate: { type: Date, required: true },
29
+ endDate: { type: Date, default: null },
30
+ },
31
+ billed: {
32
+ type: Boolean,
33
+ default: false,
34
+ index: true,
35
+ },
36
+ },
37
+ {
38
+ timestamps: true,
39
+ },
40
+ );
41
+
42
+ volumeUsageSegmentSchema.index({ user_id: 1, billed: 1, "costs.endDate": 1 });
43
+ volumeUsageSegmentSchema.index({ team_id: 1, billed: 1, "costs.endDate": 1 });
44
+ volumeUsageSegmentSchema.index({ volume_id: 1, "costs.endDate": 1 });
45
+
46
+ // Partial unique: at most one open (endDate: null) segment per volume.
47
+ // The provider relies on E11000 keyPattern.volume_id to detect race-condition duplicates.
48
+ volumeUsageSegmentSchema.index(
49
+ { volume_id: 1 },
50
+ {
51
+ unique: true,
52
+ partialFilterExpression: { "costs.endDate": null },
53
+ name: "unique_open_segment_per_volume",
54
+ },
55
+ );
56
+
57
+ export default model<IVolumeUsageSegment>(
58
+ "VolumeUsageSegment",
59
+ volumeUsageSegmentSchema,
60
+ "volume_usage_segments",
61
+ );
package/volume.ts CHANGED
@@ -17,13 +17,21 @@ const volumeSchema: Schema = new Schema(
17
17
  ref: "Team",
18
18
  default: null,
19
19
  },
20
- subscription: {
21
- type: Schema.Types.ObjectId,
22
- required: true,
23
- ref: "Subscription",
24
- },
25
20
  size: { type: Number, required: true },
26
21
  mount_path: { type: String },
22
+ csi_volume_id: { type: String, default: null },
23
+ region: { type: String, default: null },
24
+ attached_sandbox_id: {
25
+ type: Schema.Types.ObjectId,
26
+ ref: "Sandbox",
27
+ default: null,
28
+ },
29
+ attached_project_id: {
30
+ type: Schema.Types.ObjectId,
31
+ ref: "Project",
32
+ default: null,
33
+ },
34
+ last_attached_at: { type: Date, default: null },
27
35
  },
28
36
  {
29
37
  timestamps: {