1
0
mirror of https://github.com/google/nomulus synced 2026-05-18 22:01:47 +00:00

Compare commits

...

5 Commits

Author SHA1 Message Date
gbrodman
5fb95f38ed Don't always require contacts in CreateDomainCommand (#2755)
If contacts are optional, they should be optional in the command too.
2025-05-15 20:22:07 +00:00
gbrodman
dfe8e24761 Add registrar_id col to password reset requests (#2756)
This is just so that we can add an additional layer of security on
verification
2025-05-15 20:13:27 +00:00
Juan Celhay
bd30fcc81c Remove registrar id from invoice grouping key (#2749)
* Remove registrar id from invoice grouping key

* Fix formatting issues

* Update BillingEventTests
2025-05-13 20:29:25 +00:00
gbrodman
8cecc8d3a8 Use the primary DB for DomainInfoFlow (#2750)
This avoids potential replication lag issues when requesting info on
domains that were just created.
2025-05-13 18:00:30 +00:00
Pavlo Tkach
c5a39bccc5 Add Console POC reminder front-end (#2754) 2025-05-12 20:14:56 +00:00
29 changed files with 814 additions and 414 deletions

View File

@@ -14,30 +14,71 @@
import { provideHttpClient } from '@angular/common/http';
import { provideHttpClientTesting } from '@angular/common/http/testing';
import { TestBed } from '@angular/core/testing';
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
import { ComponentFixture, fakeAsync, TestBed } from '@angular/core/testing';
import { NoopAnimationsModule } from '@angular/platform-browser/animations';
import { AppComponent } from './app.component';
import { MaterialModule } from './material.module';
import { BackendService } from './shared/services/backend.service';
import { AppRoutingModule } from './app-routing.module';
import { routes } from './app-routing.module';
import { AppModule } from './app.module';
import { PocReminderComponent } from './shared/components/pocReminder/pocReminder.component';
import { RouterModule } from '@angular/router';
import { MatSnackBar, MatSnackBarModule } from '@angular/material/snack-bar';
import { UserData, UserDataService } from './shared/services/userData.service';
import { Registrar, RegistrarService } from './registrar/registrar.service';
import { MatSidenavModule } from '@angular/material/sidenav';
import { signal, WritableSignal } from '@angular/core';
describe('AppComponent', () => {
let component: AppComponent;
let fixture: ComponentFixture<AppComponent>;
let mockRegistrarService: {
registrar: WritableSignal<Partial<Registrar> | null | undefined>;
registrarId: WritableSignal<string>;
registrars: WritableSignal<Array<Partial<Registrar>>>;
};
let mockUserDataService: { userData: WritableSignal<Partial<UserData>> };
let mockSnackBar: jasmine.SpyObj<MatSnackBar>;
const dummyPocReminderComponent = class {}; // Dummy class for type checking
beforeEach(async () => {
mockRegistrarService = {
registrar: signal<Registrar | null | undefined>(undefined),
registrarId: signal('123'),
registrars: signal([]),
};
mockUserDataService = {
userData: signal({
globalRole: 'NONE',
}),
};
mockSnackBar = jasmine.createSpyObj('MatSnackBar', ['openFromComponent']);
await TestBed.configureTestingModule({
declarations: [AppComponent],
imports: [
MaterialModule,
BrowserAnimationsModule,
AppRoutingModule,
MatSidenavModule,
NoopAnimationsModule,
MatSnackBarModule,
AppModule,
RouterModule.forRoot(routes),
],
providers: [
BackendService,
{ provide: RegistrarService, useValue: mockRegistrarService },
{ provide: UserDataService, useValue: mockUserDataService },
{ provide: MatSnackBar, useValue: mockSnackBar },
{ provide: PocReminderComponent, useClass: dummyPocReminderComponent },
provideHttpClient(),
provideHttpClientTesting(),
],
}).compileComponents();
fixture = TestBed.createComponent(AppComponent);
component = fixture.componentInstance;
});
afterEach(() => {
jasmine.clock().uninstall();
});
it('should create the app', () => {
@@ -46,4 +87,51 @@ describe('AppComponent', () => {
const app = fixture.componentInstance;
expect(app).toBeTruthy();
});
describe('PoC Verification Reminder', () => {
beforeEach(() => {
jasmine.clock().install();
});
it('should open snackbar if lastPocVerificationDate is older than one year', fakeAsync(() => {
const MOCK_TODAY = new Date('2024-07-15T10:00:00.000Z');
jasmine.clock().mockDate(MOCK_TODAY);
const twoYearsAgo = new Date(MOCK_TODAY);
twoYearsAgo.setFullYear(MOCK_TODAY.getFullYear() - 2);
mockRegistrarService.registrar.set({
lastPocVerificationDate: twoYearsAgo.toISOString(),
});
fixture.detectChanges();
TestBed.flushEffects();
expect(mockSnackBar.openFromComponent).toHaveBeenCalledWith(
PocReminderComponent,
{
horizontalPosition: 'center',
verticalPosition: 'top',
duration: 1000000000,
}
);
}));
it('should NOT open snackbar if lastPocVerificationDate is within last year', fakeAsync(() => {
const MOCK_TODAY = new Date('2024-07-15T10:00:00.000Z');
jasmine.clock().mockDate(MOCK_TODAY);
const sixMonthsAgo = new Date(MOCK_TODAY);
sixMonthsAgo.setMonth(MOCK_TODAY.getMonth() - 6);
mockRegistrarService.registrar.set({
lastPocVerificationDate: sixMonthsAgo.toISOString(),
});
fixture.detectChanges();
TestBed.flushEffects();
expect(mockSnackBar.openFromComponent).not.toHaveBeenCalled();
}));
});
});

View File

@@ -12,13 +12,15 @@
// See the License for the specific language governing permissions and
// limitations under the License.
import { AfterViewInit, Component, ViewChild } from '@angular/core';
import { AfterViewInit, Component, effect, ViewChild } from '@angular/core';
import { MatSidenav } from '@angular/material/sidenav';
import { NavigationEnd, Router } from '@angular/router';
import { RegistrarService } from './registrar/registrar.service';
import { BreakPointObserverService } from './shared/services/breakPoint.service';
import { GlobalLoaderService } from './shared/services/globalLoader.service';
import { UserDataService } from './shared/services/userData.service';
import { MatSnackBar } from '@angular/material/snack-bar';
import { PocReminderComponent } from './shared/components/pocReminder/pocReminder.component';
@Component({
selector: 'app-root',
@@ -35,8 +37,28 @@ export class AppComponent implements AfterViewInit {
protected userDataService: UserDataService,
protected globalLoader: GlobalLoaderService,
protected breakpointObserver: BreakPointObserverService,
private router: Router
) {}
private router: Router,
private _snackBar: MatSnackBar
) {
effect(() => {
const registrar = this.registrarService.registrar();
const oneYearAgo = new Date();
oneYearAgo.setFullYear(oneYearAgo.getFullYear() - 1);
oneYearAgo.setHours(0, 0, 0, 0);
if (
registrar &&
registrar.lastPocVerificationDate &&
new Date(registrar.lastPocVerificationDate) < oneYearAgo &&
this.userDataService?.userData()?.globalRole === 'NONE'
) {
this._snackBar.openFromComponent(PocReminderComponent, {
horizontalPosition: 'center',
verticalPosition: 'top',
duration: 1000000000,
});
}
});
}
ngAfterViewInit() {
this.router.events.subscribe((event) => {

View File

@@ -60,6 +60,7 @@ import { TldsComponent } from './tlds/tlds.component';
import { ForceFocusDirective } from './shared/directives/forceFocus.directive';
import RdapComponent from './settings/rdap/rdap.component';
import RdapEditComponent from './settings/rdap/rdapEdit.component';
import { PocReminderComponent } from './shared/components/pocReminder/pocReminder.component';
@NgModule({
declarations: [SelectedRegistrarWrapper],
@@ -86,6 +87,7 @@ export class SelectedRegistrarModule {}
RdapComponent,
RdapEditComponent,
ReasonDialogComponent,
PocReminderComponent,
RegistrarComponent,
RegistrarDetailsComponent,
RegistrarSelectorComponent,

View File

@@ -57,7 +57,7 @@ export class NavigationComponent {
}
ngOnDestroy() {
this.subscription.unsubscribe();
this.subscription && this.subscription.unsubscribe();
}
getElementId(node: RouteWithIcon) {

View File

@@ -71,6 +71,7 @@ export interface Registrar
registrarName: string;
registryLockAllowed?: boolean;
type?: string;
lastPocVerificationDate?: string;
}
@Injectable({

View File

@@ -0,0 +1,14 @@
<div class="console-app__pocReminder">
<p class="">
Please take a moment to complete annual review of
<a routerLink="/settings">contacts</a>.
</p>
<span matSnackBarActions>
<button mat-button matSnackBarAction (click)="confirmReviewed()">
Confirm reviewed
</button>
<button mat-button matSnackBarAction (click)="snackBarRef.dismiss()">
Close
</button>
</span>
</div>

View File

@@ -0,0 +1,5 @@
.console-app__pocReminder {
a {
color: white !important;
}
}

View File

@@ -0,0 +1,53 @@
// Copyright 2025 The Nomulus Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
import { Component } from '@angular/core';
import { MatSnackBar, MatSnackBarRef } from '@angular/material/snack-bar';
import { RegistrarService } from '../../../registrar/registrar.service';
import { HttpErrorResponse } from '@angular/common/http';
@Component({
selector: 'app-poc-reminder',
templateUrl: './pocReminder.component.html',
styleUrls: ['./pocReminder.component.scss'],
standalone: false,
})
export class PocReminderComponent {
constructor(
public snackBarRef: MatSnackBarRef<PocReminderComponent>,
private registrarService: RegistrarService,
private _snackBar: MatSnackBar
) {}
confirmReviewed() {
if (this.registrarService.registrar()) {
const todayMidnight = new Date();
todayMidnight.setHours(0, 0, 0, 0);
this.registrarService
// @ts-ignore - if check above won't allow empty object to be submitted
.updateRegistrar({
...this.registrarService.registrar(),
lastPocVerificationDate: todayMidnight.toISOString(),
})
.subscribe({
error: (err: HttpErrorResponse) => {
this._snackBar.open(err.error || err.message);
},
next: () => {
this.snackBarRef.dismiss();
},
});
}
}
}

View File

@@ -172,7 +172,7 @@ public record BillingEvent(
.minusDays(1)
.toString(),
billingId(),
registrarId(),
"",
String.format("%s | TLD: %s | TERM: %d-year", action(), tld(), years()),
amount(),
currency(),

View File

@@ -31,6 +31,7 @@ import google.registry.flows.ExtensionManager;
import google.registry.flows.FlowModule.RegistrarId;
import google.registry.flows.FlowModule.Superuser;
import google.registry.flows.FlowModule.TargetId;
import google.registry.flows.MutatingFlow;
import google.registry.flows.TransactionalFlow;
import google.registry.flows.annotations.ReportingSpec;
import google.registry.flows.custom.DomainInfoFlowCustomLogic;
@@ -53,6 +54,8 @@ import google.registry.model.eppinput.ResourceCommand;
import google.registry.model.eppoutput.EppResponse;
import google.registry.model.eppoutput.EppResponse.ResponseExtension;
import google.registry.model.reporting.IcannReportingTypes.ActivityReportField;
import google.registry.persistence.IsolationLevel;
import google.registry.persistence.PersistenceModule;
import google.registry.util.Clock;
import jakarta.inject.Inject;
import java.util.Optional;
@@ -62,8 +65,12 @@ import org.joda.time.DateTime;
* An EPP flow that returns information about a domain.
*
* <p>The registrar that owns the domain, and any registrar presenting a valid authInfo for the
* domain, will get a rich result with all of the domain's fields. All other requests will be
* answered with a minimal result containing only basic information about the domain.
* domain, will get a rich result with all the domain's fields. All other requests will be answered
* with a minimal result containing only basic information about the domain.
*
* <p>This implements {@link MutatingFlow} instead of {@link TransactionalFlow} as a workaround so
* that the common workflow of "create domain, then immediately get domain info" does not run into
* replication lag issues where the info command claims the domain does not exist.
*
* @error {@link google.registry.flows.FlowUtils.NotLoggedInException}
* @error {@link google.registry.flows.FlowUtils.UnknownCurrencyEppException}
@@ -76,7 +83,8 @@ import org.joda.time.DateTime;
* @error {@link DomainFlowUtils.TransfersAreAlwaysForOneYearException}
*/
@ReportingSpec(ActivityReportField.DOMAIN_INFO)
public final class DomainInfoFlow implements TransactionalFlow {
@IsolationLevel(PersistenceModule.TransactionIsolationLevel.TRANSACTION_REPEATABLE_READ)
public final class DomainInfoFlow implements MutatingFlow {
@Inject ExtensionManager extensionManager;
@Inject ResourceCommand resourceCommand;

View File

@@ -16,6 +16,7 @@ package google.registry.tools;
import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.base.Strings.isNullOrEmpty;
import static google.registry.persistence.transaction.TransactionManagerFactory.tm;
import static google.registry.pricing.PricingEngineProxy.getPricesForDomainName;
import static google.registry.util.PreconditionsUtils.checkArgumentNotNull;
import static org.joda.time.DateTimeZone.UTC;
@@ -23,6 +24,7 @@ import static org.joda.time.DateTimeZone.UTC;
import com.beust.jcommander.Parameter;
import com.beust.jcommander.Parameters;
import com.google.template.soy.data.SoyMapData;
import google.registry.model.common.FeatureFlag;
import google.registry.model.pricing.PremiumPricingEngine.DomainPrices;
import google.registry.tools.soy.DomainCreateSoyInfo;
import google.registry.util.StringGenerator;
@@ -58,9 +60,15 @@ final class CreateDomainCommand extends CreateOrUpdateDomainCommand {
@Override
protected void initMutatingEppToolCommand() {
checkArgumentNotNull(registrant, "Registrant must be specified");
checkArgument(!admins.isEmpty(), "At least one admin must be specified");
checkArgument(!techs.isEmpty(), "At least one tech must be specified");
tm().transact(
() -> {
if (!FeatureFlag.isActiveNowOrElse(
FeatureFlag.FeatureName.MINIMUM_DATASET_CONTACTS_OPTIONAL, false)) {
checkArgumentNotNull(registrant, "Registrant must be specified");
checkArgument(!admins.isEmpty(), "At least one admin must be specified");
checkArgument(!techs.isEmpty(), "At least one tech must be specified");
}
});
if (isNullOrEmpty(password)) {
password = passwordGenerator.createString(PASSWORD_LENGTH);
}

View File

@@ -17,6 +17,7 @@ package google.registry.ui.server.console;
import static com.google.common.base.Preconditions.checkArgument;
import static google.registry.persistence.transaction.TransactionManagerFactory.tm;
import static google.registry.request.Action.Method.POST;
import static google.registry.util.DateTimeUtils.START_OF_TIME;
import static google.registry.util.PreconditionsUtils.checkArgumentPresent;
import static org.apache.http.HttpStatus.SC_OK;
@@ -37,6 +38,7 @@ import google.registry.util.RegistryEnvironment;
import jakarta.inject.Inject;
import java.util.Optional;
import java.util.stream.Collectors;
import org.joda.time.DateTime;
@Action(
service = GaeService.DEFAULT,
@@ -88,18 +90,35 @@ public class ConsoleUpdateRegistrarAction extends ConsoleApiAction {
}
}
Registrar updatedRegistrar =
DateTime now = tm().getTransactionTime();
DateTime newLastPocVerificationDate =
registrarParam.getLastPocVerificationDate() == null
? START_OF_TIME
: registrarParam.getLastPocVerificationDate();
checkArgument(
newLastPocVerificationDate.isBefore(now),
"Invalid value of LastPocVerificationDate - value is in the future");
var updatedRegistrarBuilder =
existingRegistrar
.get()
.asBuilder()
.setAllowedTlds(
registrarParam.getAllowedTlds().stream()
.map(DomainNameUtils::canonicalizeHostname)
.collect(Collectors.toSet()))
.setRegistryLockAllowed(registrarParam.isRegistryLockAllowed())
.setLastPocVerificationDate(registrarParam.getLastPocVerificationDate())
.build();
.setLastPocVerificationDate(newLastPocVerificationDate);
if (user.getUserRoles()
.hasGlobalPermission(ConsolePermission.EDIT_REGISTRAR_DETAILS)) {
updatedRegistrarBuilder =
updatedRegistrarBuilder
.setAllowedTlds(
registrarParam.getAllowedTlds().stream()
.map(DomainNameUtils::canonicalizeHostname)
.collect(Collectors.toSet()))
.setRegistryLockAllowed(registrarParam.isRegistryLockAllowed())
.setLastPocVerificationDate(newLastPocVerificationDate);
}
var updatedRegistrar = updatedRegistrarBuilder.build();
tm().put(updatedRegistrar);
finishAndPersistConsoleUpdateHistory(
new ConsoleUpdateHistory.Builder()

View File

@@ -20,9 +20,9 @@
{@param domain: string}
{@param period: int}
{@param nameservers: list<string>}
{@param registrant: string}
{@param admins: list<string>}
{@param techs: list<string>}
{@param? registrant: string|null}
{@param? admins: list<string>|null}
{@param? techs: list<string>|null}
{@param password: string}
{@param? currency: string|null}
{@param? price: string|null}
@@ -45,13 +45,19 @@
{/for}
</domain:ns>
{/if}
<domain:registrant>{$registrant}</domain:registrant>
{for $admin in $admins}
<domain:contact type="admin">{$admin}</domain:contact>
{/for}
{for $tech in $techs}
<domain:contact type="tech">{$tech}</domain:contact>
{/for}
{if $registrant != null}
<domain:registrant>{$registrant}</domain:registrant>
{/if}
{if $admins != null}
{for $admin in $admins}
<domain:contact type="admin">{$admin}</domain:contact>
{/for}
{/if}
{if $techs != null}
{for $tech in $techs}
<domain:contact type="tech">{$tech}</domain:contact>
{/for}
{/if}
<domain:authInfo>
<domain:pw>{$password}</domain:pw>
</domain:authInfo>

View File

@@ -85,7 +85,7 @@ class BillingEventTest {
assertThat(invoiceKey.startDate()).isEqualTo("2017-10-01");
assertThat(invoiceKey.endDate()).isEqualTo("2022-09-30");
assertThat(invoiceKey.productAccountKey()).isEqualTo("12345-CRRHELLO");
assertThat(invoiceKey.usageGroupingKey()).isEqualTo("myRegistrar");
assertThat(invoiceKey.usageGroupingKey()).isEqualTo("");
assertThat(invoiceKey.description()).isEqualTo("RENEW | TLD: test | TERM: 5-year");
assertThat(invoiceKey.unitPrice()).isEqualTo(20.5);
assertThat(invoiceKey.unitPriceCurrency()).isEqualTo("USD");
@@ -106,7 +106,7 @@ class BillingEventTest {
assertThat(invoiceKey.toCsv(3L))
.isEqualTo(
"2017-10-01,2022-09-30,12345-CRRHELLO,61.50,USD,10125,1,PURCHASE,"
+ "myRegistrar,3,RENEW | TLD: test | TERM: 5-year,20.50,USD,");
+ ",3,RENEW | TLD: test | TERM: 5-year,20.50,USD,");
}
@Test
@@ -116,7 +116,7 @@ class BillingEventTest {
assertThat(invoiceKey.toCsv(3L))
.isEqualTo(
"2017-10-01,,12345-CRRHELLO,61.50,USD,10125,1,PURCHASE,"
+ "myRegistrar,3,RENEW | TLD: test | TERM: 0-year,20.50,USD,");
+ ",3,RENEW | TLD: test | TERM: 0-year,20.50,USD,");
}
@Test

View File

@@ -199,6 +199,36 @@ class InvoicingPipelineTest {
0,
"USD",
20.0,
""),
google.registry.beam.billing.BillingEvent.create(
15,
DateTime.parse("2017-10-02T00:00:00.0Z"),
DateTime.parse("2017-10-04T00:00:00.0Z"),
"theRegistrarCopy",
"234",
"",
"test",
"CREATE",
"mydomainfromanotherclient.test",
"REPO-ID",
5,
"JPY",
70.0,
""),
google.registry.beam.billing.BillingEvent.create(
16,
DateTime.parse("2017-10-04T00:00:00Z"),
DateTime.parse("2017-10-04T00:00:00Z"),
"theRegistrarCopy",
"234",
"",
"test",
"RENEW",
"mydomain2fromanotherclient.test",
"REPO-ID",
3,
"USD",
20.5,
""));
private static final ImmutableMap<String, ImmutableList<String>> EXPECTED_DETAILED_REPORT_MAP =
@@ -224,18 +254,26 @@ class InvoicingPipelineTest {
"invoice_details_2017-10_anotherRegistrar_test.csv",
ImmutableList.of(
"5,2017-10-04 00:00:00 UTC,2017-10-04 00:00:00 UTC,anotherRegistrar,789,,"
+ "test,CREATE,mydomain5.test,REPO-ID,1,USD,0.00,SUNRISE ANCHOR_TENANT"));
+ "test,CREATE,mydomain5.test,REPO-ID,1,USD,0.00,SUNRISE ANCHOR_TENANT"),
"invoice_details_2017-10_theRegistrarCopy_test.csv",
ImmutableList.of(
"15,2017-10-02 00:00:00 UTC,2017-10-04 00:00:00"
+ " UTC,theRegistrarCopy,234,,test,CREATE,mydomainfromanotherclient.test,REPO-ID,5,JPY,70.00,",
"16,2017-10-04 00:00:00 UTC,2017-10-04 00:00:00"
+ " UTC,theRegistrarCopy,234,,test,RENEW,mydomain2fromanotherclient.test,REPO-ID,3,USD,20.50,"));
private static final ImmutableList<String> EXPECTED_INVOICE_OUTPUT =
ImmutableList.of(
"2017-10-01,2020-09-30,234,41.00,USD,10125,1,PURCHASE,theRegistrar,2,"
"2017-10-01,2020-09-30,234,61.50,USD,10125,1,PURCHASE,,3,"
+ "RENEW | TLD: test | TERM: 3-year,20.50,USD,",
"2017-10-01,2022-09-30,234,70.00,JPY,10125,1,PURCHASE,theRegistrar,1,"
"2017-10-01,2022-09-30,234,70.00,JPY,10125,1,PURCHASE,,1,"
+ "CREATE | TLD: hello | TERM: 5-year,70.00,JPY,",
"2017-10-01,,234,20.00,USD,10125,1,PURCHASE,theRegistrar,1,"
"2017-10-01,,234,20.00,USD,10125,1,PURCHASE,,1,"
+ "SERVER_STATUS | TLD: test | TERM: 0-year,20.00,USD,",
"2017-10-01,2018-09-30,456,20.50,USD,10125,1,PURCHASE,bestdomains,1,"
+ "RENEW | TLD: test | TERM: 1-year,20.50,USD,116688");
"2017-10-01,2018-09-30,456,20.50,USD,10125,1,PURCHASE,,1,"
+ "RENEW | TLD: test | TERM: 1-year,20.50,USD,116688",
"2017-10-01,2022-09-30,234,70.00,JPY,10125,1,PURCHASE,,1,CREATE | TLD: test | TERM:"
+ " 5-year,70.00,JPY,");
private final InvoicingPipelineOptions options =
PipelineOptionsFactory.create().as(InvoicingPipelineOptions.class);
@@ -355,21 +393,21 @@ class InvoicingPipelineTest {
.isEqualTo(
"""
SELECT b, r FROM BillingEvent b
JOIN Registrar r ON b.clientId = r.registrarId
JOIN Domain d ON b.domainRepoId = d.repoId
JOIN Tld t ON t.tldStr = d.tld
LEFT JOIN BillingCancellation c ON b.id = c.billingEvent
LEFT JOIN BillingCancellation cr ON b.cancellationMatchingBillingEvent = cr.billingRecurrence
WHERE r.billingAccountMap IS NOT NULL
AND r.type = 'REAL'
AND t.invoicingEnabled IS TRUE
AND CAST(b.billingTime AS timestamp)
BETWEEN CAST('2017-10-01T00:00:00Z' AS timestamp)
AND CAST('2017-11-01T00:00:00Z' AS timestamp)
AND c.id IS NULL
AND cr.id IS NULL
""");
SELECT b, r FROM BillingEvent b
JOIN Registrar r ON b.clientId = r.registrarId
JOIN Domain d ON b.domainRepoId = d.repoId
JOIN Tld t ON t.tldStr = d.tld
LEFT JOIN BillingCancellation c ON b.id = c.billingEvent
LEFT JOIN BillingCancellation cr ON b.cancellationMatchingBillingEvent = cr.billingRecurrence
WHERE r.billingAccountMap IS NOT NULL
AND r.type = 'REAL'
AND t.invoicingEnabled IS TRUE
AND CAST(b.billingTime AS timestamp)
BETWEEN CAST('2017-10-01T00:00:00Z' AS timestamp)
AND CAST('2017-11-01T00:00:00Z' AS timestamp)
AND c.id IS NULL
AND cr.id IS NULL
""");
}
/** Returns the text contents of a file under the beamBucket/results directory. */
@@ -391,6 +429,13 @@ class InvoicingPipelineTest {
.setBillingAccountMap(ImmutableMap.of(JPY, "234", USD, "234"))
.build();
persistResource(registrar1);
Registrar registrar11 = persistNewRegistrar("theRegistrarCopy");
registrar11 =
registrar11
.asBuilder()
.setBillingAccountMap(ImmutableMap.of(JPY, "234", USD, "234"))
.build();
persistResource(registrar11);
Registrar registrar2 = persistNewRegistrar("bestdomains");
registrar2 =
registrar2
@@ -547,6 +592,21 @@ class InvoicingPipelineTest {
.setDomainHistory(domainHistoryRecurrence)
.build();
persistResource(cancellationRecurrence);
// Domains created for registrar with = key but != client id.
Domain domain14 = persistActiveDomain("mydomainfromanotherclient.test");
Domain domain15 = persistActiveDomain("mydomain2fromanotherclient.test");
persistBillingEvent(
15,
domain14,
registrar11,
Reason.CREATE,
5,
Money.ofMajor(JPY, 70),
DateTime.parse("2017-10-04T00:00:00.0Z"),
DateTime.parse("2017-10-02T00:00:00.0Z"));
persistBillingEvent(16, domain15, registrar11, Reason.RENEW, 3, Money.of(USD, 20.5));
}
private static DomainHistory persistDomainHistory(Domain domain, Registrar registrar) {

View File

@@ -58,7 +58,7 @@ public class FlowModuleTest {
@Test
void givenNonMutatingFlow_thenReplicaTmIsUsed() throws EppException {
String eppInputXmlFilename = "domain_info.xml";
String eppInputXmlFilename = "domain_check.xml";
FlowModule flowModule =
new FlowModule.Builder().setEppInput(getEppInput(eppInputXmlFilename)).build();
JpaTransactionManager tm =

View File

@@ -179,7 +179,7 @@ class DomainInfoFlowTest extends ResourceFlowTestCase<DomainInfoFlow, Domain> {
ImmutableMap<String, String> substitutions,
boolean expectHistoryAndBilling)
throws Exception {
assertMutatingFlow(false);
assertMutatingFlow(true);
String expected =
loadFile(expectedXmlFilename, updateSubstitutions(substitutions, "ROID", "2FF-TLD"));
if (inactive) {

View File

@@ -15,16 +15,21 @@
package google.registry.tools;
import static com.google.common.truth.Truth.assertThat;
import static google.registry.model.common.FeatureFlag.FeatureName.MINIMUM_DATASET_CONTACTS_OPTIONAL;
import static google.registry.model.common.FeatureFlag.FeatureStatus.ACTIVE;
import static google.registry.persistence.transaction.TransactionManagerFactory.tm;
import static google.registry.testing.DatabaseHelper.createTld;
import static google.registry.testing.DatabaseHelper.persistPremiumList;
import static google.registry.testing.DatabaseHelper.persistResource;
import static google.registry.util.DateTimeUtils.START_OF_TIME;
import static org.joda.money.CurrencyUnit.JPY;
import static org.junit.jupiter.api.Assertions.assertThrows;
import com.beust.jcommander.ParameterException;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.ImmutableSortedMap;
import google.registry.dns.writer.VoidDnsWriter;
import google.registry.model.common.FeatureFlag;
import google.registry.model.pricing.StaticPremiumListPricingEngine;
import google.registry.model.tld.Tld;
import google.registry.model.tld.label.PremiumListDao;
@@ -111,12 +116,15 @@ class CreateDomainCommandTest extends EppToolCommandTestCase<CreateDomainCommand
@Test
void testSuccess_minimal() throws Exception {
persistResource(
new FeatureFlag()
.asBuilder()
.setFeatureName(MINIMUM_DATASET_CONTACTS_OPTIONAL)
.setStatusMap(ImmutableSortedMap.of(START_OF_TIME, ACTIVE))
.build());
// Test that each optional field can be omitted. Also tests the auto-gen password.
runCommandForced(
"--client=NewRegistrar",
"--registrant=crr-admin",
"--admins=crr-admin",
"--techs=crr-tech",
"example.tld");
eppVerifier.verifySent("domain_create_minimal.xml");
}
@@ -131,7 +139,9 @@ class CreateDomainCommandTest extends EppToolCommandTestCase<CreateDomainCommand
"--techs=crr-tech",
"example.tld",
"example.abc");
eppVerifier.verifySent("domain_create_minimal.xml").verifySent("domain_create_minimal_abc.xml");
eppVerifier
.verifySent("domain_create_contacts.xml")
.verifySent("domain_create_contacts_abc.xml");
}
@Test
@@ -152,8 +162,8 @@ class CreateDomainCommandTest extends EppToolCommandTestCase<CreateDomainCommand
"example.tld",
"example.abc");
eppVerifier
.verifySent("domain_create_minimal.xml")
.verifySent("domain_create_minimal_abc.xml");
.verifySent("domain_create_contacts.xml")
.verifySent("domain_create_contacts_abc.xml");
}
@Test
@@ -192,9 +202,9 @@ class CreateDomainCommandTest extends EppToolCommandTestCase<CreateDomainCommand
"palladium.tld",
"example.abc");
eppVerifier
.verifySent("domain_create_minimal.xml")
.verifySent("domain_create_contacts.xml")
.verifySent("domain_create_palladium.xml")
.verifySent("domain_create_minimal_abc.xml");
.verifySent("domain_create_contacts_abc.xml");
assertInStdout(
"palladium.tld is premium at USD 877.00 per year; "
+ "sending total cost for 1 year(s) of USD 877.00.");
@@ -227,6 +237,19 @@ class CreateDomainCommandTest extends EppToolCommandTestCase<CreateDomainCommand
eppVerifier.verifySent("domain_create_token.xml");
}
@Test
void testSuccess_contactsStillRequired() throws Exception {
// Verify that if contacts are still required, the minimum+contacts request is sent
createTld("tld");
runCommandForced(
"--client=NewRegistrar",
"--registrant=crr-admin",
"--admins=crr-admin",
"--techs=crr-tech",
"example.tld");
eppVerifier.verifySent("domain_create_contacts.xml");
}
@Test
void testFailure_duplicateDomains() {
IllegalArgumentException thrown =

View File

@@ -40,6 +40,7 @@ import google.registry.request.Action;
import google.registry.request.RequestModule;
import google.registry.request.auth.AuthResult;
import google.registry.testing.ConsoleApiParamsUtils;
import google.registry.testing.FakeClock;
import google.registry.testing.FakeResponse;
import google.registry.testing.SystemPropertyExtension;
import google.registry.tools.GsonUtils;
@@ -51,6 +52,7 @@ import java.io.BufferedReader;
import java.io.IOException;
import java.io.StringReader;
import java.util.Optional;
import org.joda.time.DateTime;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Order;
import org.junit.jupiter.api.Test;
@@ -59,7 +61,7 @@ import org.junit.jupiter.api.extension.RegisterExtension;
/** Tests for {@link google.registry.ui.server.console.ConsoleUpdateRegistrarAction}. */
class ConsoleUpdateRegistrarActionTest {
private static final Gson GSON = GsonUtils.provideGson();
private final FakeClock clock = new FakeClock(DateTime.parse("2025-01-01T00:00:00.000Z"));
private ConsoleApiParams consoleApiParams;
private FakeResponse response;
@@ -75,6 +77,10 @@ class ConsoleUpdateRegistrarActionTest {
@Order(Integer.MAX_VALUE)
final SystemPropertyExtension systemPropertyExtension = new SystemPropertyExtension();
@RegisterExtension
final JpaTestExtensions.JpaIntegrationTestExtension jpa =
new JpaTestExtensions.Builder().withClock(clock).buildIntegrationTestExtension();
@BeforeEach
void beforeEach() throws Exception {
createTlds("app", "dev");
@@ -95,10 +101,6 @@ class ConsoleUpdateRegistrarActionTest {
consoleApiParams = createParams();
}
@RegisterExtension
final JpaTestExtensions.JpaIntegrationTestExtension jpa =
new JpaTestExtensions.Builder().buildIntegrationTestExtension();
@Test
void testSuccess_updatesRegistrar() throws IOException {
var action =
@@ -108,7 +110,7 @@ class ConsoleUpdateRegistrarActionTest {
"TheRegistrar",
"app, dev",
false,
"\"2025-01-01T00:00:00.000Z\""));
"\"2024-12-12T00:00:00.000Z\""));
action.run();
Registrar newRegistrar = Registrar.loadByRegistrarId("TheRegistrar").get();
assertThat(newRegistrar.getAllowedTlds()).containsExactly("app", "dev");
@@ -119,6 +121,33 @@ class ConsoleUpdateRegistrarActionTest {
assertThat(history.getDescription()).hasValue("TheRegistrar");
}
@Test
void testSuccess_updatesNullPocVerificationDate() throws IOException {
var action =
createAction(
String.format(registrarPostData, "TheRegistrar", "app, dev", false, "\"null\""));
action.run();
Registrar newRegistrar = Registrar.loadByRegistrarId("TheRegistrar").get();
assertThat(newRegistrar.getLastPocVerificationDate())
.isEqualTo(DateTime.parse("1970-01-01T00:00:00.000Z"));
}
@Test
void testFailure_pocVerificationInTheFuture() throws IOException {
var action =
createAction(
String.format(
registrarPostData,
"TheRegistrar",
"app, dev",
false,
"\"2025-02-01T00:00:00.000Z\""));
action.run();
assertThat(((FakeResponse) consoleApiParams.response()).getStatus()).isEqualTo(SC_BAD_REQUEST);
assertThat((String) ((FakeResponse) consoleApiParams.response()).getPayload())
.contains("Invalid value of LastPocVerificationDate - value is in the future");
}
@Test
void testFails_missingWhoisContact() throws IOException {
RegistryEnvironment.PRODUCTION.setup(systemPropertyExtension);
@@ -129,7 +158,7 @@ class ConsoleUpdateRegistrarActionTest {
"TheRegistrar",
"app, dev",
false,
"\"2025-01-01T00:00:00.000Z\""));
"\"2024-12-12T00:00:00.000Z\""));
action.run();
assertThat(((FakeResponse) consoleApiParams.response()).getStatus()).isEqualTo(SC_BAD_REQUEST);
assertThat((String) ((FakeResponse) consoleApiParams.response()).getPayload())
@@ -159,7 +188,7 @@ class ConsoleUpdateRegistrarActionTest {
"TheRegistrar",
"app, dev",
false,
"\"2025-01-01T00:00:00.000Z\""));
"\"2024-12-12T00:00:00.000Z\""));
action.run();
Registrar newRegistrar = Registrar.loadByRegistrarId("TheRegistrar").get();
assertThat(newRegistrar.getAllowedTlds()).containsExactly("app", "dev");
@@ -176,7 +205,7 @@ class ConsoleUpdateRegistrarActionTest {
"TheRegistrar",
"app, dev",
false,
"\"2025-01-01T00:00:00.000Z\""));
"\"2024-12-12T00:00:00.000Z\""));
action.run();
verify(consoleApiParams.sendEmailUtils().gmailClient, times(1))
.sendEmail(
@@ -190,7 +219,7 @@ class ConsoleUpdateRegistrarActionTest {
+ "\n"
+ "allowedTlds: null -> [app, dev]\n"
+ "lastPocVerificationDate: 1970-01-01T00:00:00.000Z ->"
+ " 2025-01-01T00:00:00.000Z\n")
+ " 2024-12-12T00:00:00.000Z\n")
.setRecipients(ImmutableList.of(new InternetAddress("notification@test.example")))
.build());
}

View File

@@ -16,12 +16,16 @@ package google.registry.webdriver;
import static com.google.common.truth.Truth.assertThat;
import static google.registry.server.Fixture.BASIC;
import static google.registry.testing.DatabaseHelper.persistResource;
import com.google.common.collect.ImmutableMap;
import google.registry.model.console.GlobalRole;
import google.registry.model.console.RegistrarRole;
import google.registry.model.registrar.Registrar;
import google.registry.server.RegistryTestServer;
import java.util.List;
import org.joda.time.DateTime;
import org.joda.time.DateTimeZone;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Timeout;
import org.junit.jupiter.api.condition.EnabledIfSystemProperty;
@@ -74,6 +78,10 @@ public class ConsoleScreenshotTest {
@BeforeEach
void beforeEach() throws Exception {
server.setRegistrarRoles(ImmutableMap.of("TheRegistrar", RegistrarRole.ACCOUNT_MANAGER));
Registrar registrar = Registrar.loadByRegistrarId("TheRegistrar").get();
registrar =
registrar.asBuilder().setLastPocVerificationDate(DateTime.now(DateTimeZone.UTC)).build();
persistResource(registrar);
loadHomePage();
}

View File

@@ -0,0 +1,11 @@
<epp xmlns="urn:ietf:params:xml:ns:epp-1.0">
<command>
<check>
<domain:check
xmlns:domain="urn:ietf:params:xml:ns:domain-1.0">
<domain:name>%DOMAIN%</domain:name>
</domain:check>
</check>
<clTRID>ABC-12345</clTRID>
</command>
</epp>

View File

@@ -0,0 +1,19 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<epp xmlns="urn:ietf:params:xml:ns:epp-1.0">
<command>
<create>
<domain:create
xmlns:domain="urn:ietf:params:xml:ns:domain-1.0">
<domain:name>example.tld</domain:name>
<domain:period unit="y">1</domain:period>
<domain:registrant>crr-admin</domain:registrant>
<domain:contact type="admin">crr-admin</domain:contact>
<domain:contact type="tech">crr-tech</domain:contact>
<domain:authInfo>
<domain:pw>abcdefghijklmnop</domain:pw>
</domain:authInfo>
</domain:create>
</create>
<clTRID>RegistryTool</clTRID>
</command>
</epp>

View File

@@ -6,9 +6,6 @@
xmlns:domain="urn:ietf:params:xml:ns:domain-1.0">
<domain:name>example.tld</domain:name>
<domain:period unit="y">1</domain:period>
<domain:registrant>crr-admin</domain:registrant>
<domain:contact type="admin">crr-admin</domain:contact>
<domain:contact type="tech">crr-tech</domain:contact>
<domain:authInfo>
<domain:pw>abcdefghijklmnop</domain:pw>
</domain:authInfo>

View File

@@ -261,11 +261,11 @@ td.section {
</tr>
<tr>
<td class="property_name">generated on</td>
<td class="property_value">2025-04-30 16:04:48</td>
<td class="property_value">2025-05-15 19:22:21</td>
</tr>
<tr>
<td class="property_name">last flyway file</td>
<td id="lastFlywayFile" class="property_value">V193__password_reset_request.sql</td>
<td id="lastFlywayFile" class="property_value">V194__password_reset_request_registrar.sql</td>
</tr>
</tbody>
</table>
@@ -280,7 +280,7 @@ td.section {
<text text-anchor="start" x="4655" y="-29.8" font-family="Helvetica,sans-Serif" font-size="14.00">generated by</text>
<text text-anchor="start" x="4738" y="-29.8" font-family="Helvetica,sans-Serif" font-size="14.00">SchemaCrawler 16.25.2</text>
<text text-anchor="start" x="4654" y="-10.8" font-family="Helvetica,sans-Serif" font-size="14.00">generated on</text>
<text text-anchor="start" x="4738" y="-10.8" font-family="Helvetica,sans-Serif" font-size="14.00">2025-04-30 16:04:48</text>
<text text-anchor="start" x="4738" y="-10.8" font-family="Helvetica,sans-Serif" font-size="14.00">2025-05-15 19:22:21</text>
<polygon fill="none" stroke="#888888" points="4651,-4 4651,-44 4887,-44 4887,-4 4651,-4" /> <!-- allocationtoken_a08ccbef -->
<g id="node1" class="node">
<title>

View File

@@ -261,26 +261,26 @@ td.section {
</tr>
<tr>
<td class="property_name">generated on</td>
<td class="property_value">2025-04-30 16:04:45</td>
<td class="property_value">2025-05-15 19:22:16</td>
</tr>
<tr>
<td class="property_name">last flyway file</td>
<td id="lastFlywayFile" class="property_value">V193__password_reset_request.sql</td>
<td id="lastFlywayFile" class="property_value">V194__password_reset_request_registrar.sql</td>
</tr>
</tbody>
</table>
<p>&nbsp;</p>
<p>&nbsp;</p>
<svg viewBox="0.00 0.00 5683.00 8128.00" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" id="erDiagram" style="overflow: hidden; width: 100%; height: 800px">
<g id="graph0" class="graph" transform="scale(1 1) rotate(0) translate(4 8124)">
<svg viewBox="0.00 0.00 5683.00 8146.00" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" id="erDiagram" style="overflow: hidden; width: 100%; height: 800px">
<g id="graph0" class="graph" transform="scale(1 1) rotate(0) translate(4 8142)">
<title>
SchemaCrawler_Diagram
</title>
<polygon fill="white" stroke="transparent" points="-4,4 -4,-8124 5679,-8124 5679,4 -4,4" />
<polygon fill="white" stroke="transparent" points="-4,4 -4,-8142 5679,-8142 5679,4 -4,4" />
<text text-anchor="start" x="5435" y="-29.8" font-family="Helvetica,sans-Serif" font-size="14.00">generated by</text>
<text text-anchor="start" x="5518" y="-29.8" font-family="Helvetica,sans-Serif" font-size="14.00">SchemaCrawler 16.25.2</text>
<text text-anchor="start" x="5434" y="-10.8" font-family="Helvetica,sans-Serif" font-size="14.00">generated on</text>
<text text-anchor="start" x="5518" y="-10.8" font-family="Helvetica,sans-Serif" font-size="14.00">2025-04-30 16:04:45</text>
<text text-anchor="start" x="5518" y="-10.8" font-family="Helvetica,sans-Serif" font-size="14.00">2025-05-15 19:22:16</text>
<polygon fill="none" stroke="#888888" points="5431,-4 5431,-44 5667,-44 5667,-4 5431,-4" /> <!-- allocationtoken_a08ccbef -->
<g id="node1" class="node">
<title>
@@ -3168,113 +3168,116 @@ td.section {
<title>
passwordresetrequest_8484e7b1
</title>
<polygon fill="#e9c2f2" stroke="transparent" points="5267,-6516 5267,-6535 5483,-6535 5483,-6516 5267,-6516" />
<text text-anchor="start" x="5269" y="-6522.8" font-family="Helvetica,sans-Serif" font-weight="bold" font-style="italic" font-size="14.00">public."PasswordResetRequest"</text>
<polygon fill="#e9c2f2" stroke="transparent" points="5483,-6516 5483,-6535 5609,-6535 5609,-6516 5483,-6516" />
<text text-anchor="start" x="5570" y="-6521.8" font-family="Helvetica,sans-Serif" font-size="14.00">[table]</text>
<text text-anchor="start" x="5269" y="-6502.8" font-family="Helvetica,sans-Serif" font-size="14.00">type</text>
<polygon fill="#e9c2f2" stroke="transparent" points="5267,-6535 5267,-6554 5483,-6554 5483,-6535 5267,-6535" />
<text text-anchor="start" x="5269" y="-6541.8" font-family="Helvetica,sans-Serif" font-weight="bold" font-style="italic" font-size="14.00">public."PasswordResetRequest"</text>
<polygon fill="#e9c2f2" stroke="transparent" points="5483,-6535 5483,-6554 5609,-6554 5609,-6535 5483,-6535" />
<text text-anchor="start" x="5570" y="-6540.8" font-family="Helvetica,sans-Serif" font-size="14.00">[table]</text>
<text text-anchor="start" x="5269" y="-6521.8" font-family="Helvetica,sans-Serif" font-size="14.00">type</text>
<text text-anchor="start" x="5431" y="-6521.8" font-family="Helvetica,sans-Serif" font-size="14.00"> </text>
<text text-anchor="start" x="5485" y="-6521.8" font-family="Helvetica,sans-Serif" font-size="14.00">text not null</text>
<text text-anchor="start" x="5269" y="-6502.8" font-family="Helvetica,sans-Serif" font-size="14.00">request_time</text>
<text text-anchor="start" x="5431" y="-6502.8" font-family="Helvetica,sans-Serif" font-size="14.00"> </text>
<text text-anchor="start" x="5485" y="-6502.8" font-family="Helvetica,sans-Serif" font-size="14.00">text not null</text>
<text text-anchor="start" x="5269" y="-6483.8" font-family="Helvetica,sans-Serif" font-size="14.00">request_time</text>
<text text-anchor="start" x="5485" y="-6502.8" font-family="Helvetica,sans-Serif" font-size="14.00">timestamptz not null</text>
<text text-anchor="start" x="5269" y="-6483.8" font-family="Helvetica,sans-Serif" font-size="14.00">requester</text>
<text text-anchor="start" x="5431" y="-6483.8" font-family="Helvetica,sans-Serif" font-size="14.00"> </text>
<text text-anchor="start" x="5485" y="-6483.8" font-family="Helvetica,sans-Serif" font-size="14.00">timestamptz not null</text>
<text text-anchor="start" x="5269" y="-6464.8" font-family="Helvetica,sans-Serif" font-size="14.00">requester</text>
<text text-anchor="start" x="5485" y="-6483.8" font-family="Helvetica,sans-Serif" font-size="14.00">text not null</text>
<text text-anchor="start" x="5269" y="-6464.8" font-family="Helvetica,sans-Serif" font-size="14.00">fulfillment_time</text>
<text text-anchor="start" x="5431" y="-6464.8" font-family="Helvetica,sans-Serif" font-size="14.00"> </text>
<text text-anchor="start" x="5485" y="-6464.8" font-family="Helvetica,sans-Serif" font-size="14.00">text not null</text>
<text text-anchor="start" x="5269" y="-6445.8" font-family="Helvetica,sans-Serif" font-size="14.00">fulfillment_time</text>
<text text-anchor="start" x="5485" y="-6464.8" font-family="Helvetica,sans-Serif" font-size="14.00">timestamptz</text>
<text text-anchor="start" x="5269" y="-6445.8" font-family="Helvetica,sans-Serif" font-size="14.00">destination_email</text>
<text text-anchor="start" x="5431" y="-6445.8" font-family="Helvetica,sans-Serif" font-size="14.00"> </text>
<text text-anchor="start" x="5485" y="-6445.8" font-family="Helvetica,sans-Serif" font-size="14.00">timestamptz</text>
<text text-anchor="start" x="5269" y="-6426.8" font-family="Helvetica,sans-Serif" font-size="14.00">destination_email</text>
<text text-anchor="start" x="5485" y="-6445.8" font-family="Helvetica,sans-Serif" font-size="14.00">text not null</text>
<text text-anchor="start" x="5269" y="-6427.8" font-family="Helvetica,sans-Serif" font-weight="bold" font-style="italic" font-size="14.00">verification_code</text>
<text text-anchor="start" x="5431" y="-6426.8" font-family="Helvetica,sans-Serif" font-size="14.00"> </text>
<text text-anchor="start" x="5485" y="-6426.8" font-family="Helvetica,sans-Serif" font-size="14.00">text not null</text>
<text text-anchor="start" x="5269" y="-6408.8" font-family="Helvetica,sans-Serif" font-weight="bold" font-style="italic" font-size="14.00">verification_code</text>
<text text-anchor="start" x="5269" y="-6407.8" font-family="Helvetica,sans-Serif" font-size="14.00">registrar_id</text>
<text text-anchor="start" x="5431" y="-6407.8" font-family="Helvetica,sans-Serif" font-size="14.00"> </text>
<text text-anchor="start" x="5485" y="-6407.8" font-family="Helvetica,sans-Serif" font-size="14.00">text not null</text>
<polygon fill="none" stroke="#888888" points="5266,-6401.5 5266,-6536.5 5610,-6536.5 5610,-6401.5 5266,-6401.5" />
<polygon fill="none" stroke="#888888" points="5266,-6401 5266,-6555 5610,-6555 5610,-6401 5266,-6401" />
</g> <!-- premiumentry_b0060b91 -->
<g id="node33" class="node">
<title>
premiumentry_b0060b91
</title>
<polygon fill="#e9c2f2" stroke="transparent" points="5291,-6621 5291,-6640 5446,-6640 5446,-6621 5291,-6621" />
<text text-anchor="start" x="5293" y="-6627.8" font-family="Helvetica,sans-Serif" font-weight="bold" font-style="italic" font-size="14.00">public."PremiumEntry"</text>
<polygon fill="#e9c2f2" stroke="transparent" points="5446,-6621 5446,-6640 5586,-6640 5586,-6621 5446,-6621" />
<text text-anchor="start" x="5547" y="-6626.8" font-family="Helvetica,sans-Serif" font-size="14.00">[table]</text>
<text text-anchor="start" x="5293" y="-6608.8" font-family="Helvetica,sans-Serif" font-weight="bold" font-style="italic" font-size="14.00">revision_id</text>
<text text-anchor="start" x="5412" y="-6607.8" font-family="Helvetica,sans-Serif" font-size="14.00"> </text>
<text text-anchor="start" x="5448" y="-6607.8" font-family="Helvetica,sans-Serif" font-size="14.00">int8 not null</text>
<text text-anchor="start" x="5293" y="-6588.8" font-family="Helvetica,sans-Serif" font-size="14.00">price</text>
<text text-anchor="start" x="5412" y="-6588.8" font-family="Helvetica,sans-Serif" font-size="14.00"> </text>
<text text-anchor="start" x="5448" y="-6588.8" font-family="Helvetica,sans-Serif" font-size="14.00">numeric(19, 2) not null</text>
<text text-anchor="start" x="5293" y="-6570.8" font-family="Helvetica,sans-Serif" font-weight="bold" font-style="italic" font-size="14.00">domain_label</text>
<text text-anchor="start" x="5412" y="-6569.8" font-family="Helvetica,sans-Serif" font-size="14.00"> </text>
<text text-anchor="start" x="5448" y="-6569.8" font-family="Helvetica,sans-Serif" font-size="14.00">text not null</text>
<polygon fill="none" stroke="#888888" points="5289.5,-6563 5289.5,-6641 5586.5,-6641 5586.5,-6563 5289.5,-6563" />
<polygon fill="#e9c2f2" stroke="transparent" points="5291,-6639 5291,-6658 5446,-6658 5446,-6639 5291,-6639" />
<text text-anchor="start" x="5293" y="-6645.8" font-family="Helvetica,sans-Serif" font-weight="bold" font-style="italic" font-size="14.00">public."PremiumEntry"</text>
<polygon fill="#e9c2f2" stroke="transparent" points="5446,-6639 5446,-6658 5586,-6658 5586,-6639 5446,-6639" />
<text text-anchor="start" x="5547" y="-6644.8" font-family="Helvetica,sans-Serif" font-size="14.00">[table]</text>
<text text-anchor="start" x="5293" y="-6626.8" font-family="Helvetica,sans-Serif" font-weight="bold" font-style="italic" font-size="14.00">revision_id</text>
<text text-anchor="start" x="5412" y="-6625.8" font-family="Helvetica,sans-Serif" font-size="14.00"> </text>
<text text-anchor="start" x="5448" y="-6625.8" font-family="Helvetica,sans-Serif" font-size="14.00">int8 not null</text>
<text text-anchor="start" x="5293" y="-6606.8" font-family="Helvetica,sans-Serif" font-size="14.00">price</text>
<text text-anchor="start" x="5412" y="-6606.8" font-family="Helvetica,sans-Serif" font-size="14.00"> </text>
<text text-anchor="start" x="5448" y="-6606.8" font-family="Helvetica,sans-Serif" font-size="14.00">numeric(19, 2) not null</text>
<text text-anchor="start" x="5293" y="-6588.8" font-family="Helvetica,sans-Serif" font-weight="bold" font-style="italic" font-size="14.00">domain_label</text>
<text text-anchor="start" x="5412" y="-6587.8" font-family="Helvetica,sans-Serif" font-size="14.00"> </text>
<text text-anchor="start" x="5448" y="-6587.8" font-family="Helvetica,sans-Serif" font-size="14.00">text not null</text>
<polygon fill="none" stroke="#888888" points="5289.5,-6581 5289.5,-6659 5586.5,-6659 5586.5,-6581 5289.5,-6581" />
</g> <!-- premiumlist_7c3ea68b -->
<g id="node34" class="node">
<title>
premiumlist_7c3ea68b
</title>
<polygon fill="#e9c2f2" stroke="transparent" points="4618,-6621 4618,-6640 4763,-6640 4763,-6621 4618,-6621" />
<text text-anchor="start" x="4620" y="-6627.8" font-family="Helvetica,sans-Serif" font-weight="bold" font-style="italic" font-size="14.00">public."PremiumList"</text>
<polygon fill="#e9c2f2" stroke="transparent" points="4763,-6621 4763,-6640 4873,-6640 4873,-6621 4763,-6621" />
<text text-anchor="start" x="4834" y="-6626.8" font-family="Helvetica,sans-Serif" font-size="14.00">[table]</text>
<text text-anchor="start" x="4620" y="-6608.8" font-family="Helvetica,sans-Serif" font-weight="bold" font-style="italic" font-size="14.00">revision_id</text>
<text text-anchor="start" x="4750" y="-6607.8" font-family="Helvetica,sans-Serif" font-size="14.00"> </text>
<text text-anchor="start" x="4765" y="-6607.8" font-family="Helvetica,sans-Serif" font-size="14.00">bigserial not null</text>
<text text-anchor="start" x="4750" y="-6588.8" font-family="Helvetica,sans-Serif" font-size="14.00"> </text>
<text text-anchor="start" x="4765" y="-6588.8" font-family="Helvetica,sans-Serif" font-size="14.00">auto-incremented</text>
<text text-anchor="start" x="4620" y="-6569.8" font-family="Helvetica,sans-Serif" font-size="14.00">creation_timestamp</text>
<text text-anchor="start" x="4750" y="-6569.8" font-family="Helvetica,sans-Serif" font-size="14.00"> </text>
<text text-anchor="start" x="4765" y="-6569.8" font-family="Helvetica,sans-Serif" font-size="14.00">timestamptz</text>
<text text-anchor="start" x="4620" y="-6550.8" font-family="Helvetica,sans-Serif" font-size="14.00">name</text>
<text text-anchor="start" x="4750" y="-6550.8" font-family="Helvetica,sans-Serif" font-size="14.00"> </text>
<text text-anchor="start" x="4765" y="-6550.8" font-family="Helvetica,sans-Serif" font-size="14.00">text not null</text>
<text text-anchor="start" x="4620" y="-6531.8" font-family="Helvetica,sans-Serif" font-size="14.00">bloom_filter</text>
<text text-anchor="start" x="4750" y="-6531.8" font-family="Helvetica,sans-Serif" font-size="14.00"> </text>
<text text-anchor="start" x="4765" y="-6531.8" font-family="Helvetica,sans-Serif" font-size="14.00">bytea not null</text>
<text text-anchor="start" x="4620" y="-6512.8" font-family="Helvetica,sans-Serif" font-size="14.00">currency</text>
<text text-anchor="start" x="4750" y="-6512.8" font-family="Helvetica,sans-Serif" font-size="14.00"> </text>
<text text-anchor="start" x="4765" y="-6512.8" font-family="Helvetica,sans-Serif" font-size="14.00">text not null</text>
<polygon fill="none" stroke="#888888" points="4616.5,-6506.5 4616.5,-6641.5 4873.5,-6641.5 4873.5,-6506.5 4616.5,-6506.5" />
<polygon fill="#e9c2f2" stroke="transparent" points="4618,-6639 4618,-6658 4763,-6658 4763,-6639 4618,-6639" />
<text text-anchor="start" x="4620" y="-6645.8" font-family="Helvetica,sans-Serif" font-weight="bold" font-style="italic" font-size="14.00">public."PremiumList"</text>
<polygon fill="#e9c2f2" stroke="transparent" points="4763,-6639 4763,-6658 4873,-6658 4873,-6639 4763,-6639" />
<text text-anchor="start" x="4834" y="-6644.8" font-family="Helvetica,sans-Serif" font-size="14.00">[table]</text>
<text text-anchor="start" x="4620" y="-6626.8" font-family="Helvetica,sans-Serif" font-weight="bold" font-style="italic" font-size="14.00">revision_id</text>
<text text-anchor="start" x="4750" y="-6625.8" font-family="Helvetica,sans-Serif" font-size="14.00"> </text>
<text text-anchor="start" x="4765" y="-6625.8" font-family="Helvetica,sans-Serif" font-size="14.00">bigserial not null</text>
<text text-anchor="start" x="4750" y="-6606.8" font-family="Helvetica,sans-Serif" font-size="14.00"> </text>
<text text-anchor="start" x="4765" y="-6606.8" font-family="Helvetica,sans-Serif" font-size="14.00">auto-incremented</text>
<text text-anchor="start" x="4620" y="-6587.8" font-family="Helvetica,sans-Serif" font-size="14.00">creation_timestamp</text>
<text text-anchor="start" x="4750" y="-6587.8" font-family="Helvetica,sans-Serif" font-size="14.00"> </text>
<text text-anchor="start" x="4765" y="-6587.8" font-family="Helvetica,sans-Serif" font-size="14.00">timestamptz</text>
<text text-anchor="start" x="4620" y="-6568.8" font-family="Helvetica,sans-Serif" font-size="14.00">name</text>
<text text-anchor="start" x="4750" y="-6568.8" font-family="Helvetica,sans-Serif" font-size="14.00"> </text>
<text text-anchor="start" x="4765" y="-6568.8" font-family="Helvetica,sans-Serif" font-size="14.00">text not null</text>
<text text-anchor="start" x="4620" y="-6549.8" font-family="Helvetica,sans-Serif" font-size="14.00">bloom_filter</text>
<text text-anchor="start" x="4750" y="-6549.8" font-family="Helvetica,sans-Serif" font-size="14.00"> </text>
<text text-anchor="start" x="4765" y="-6549.8" font-family="Helvetica,sans-Serif" font-size="14.00">bytea not null</text>
<text text-anchor="start" x="4620" y="-6530.8" font-family="Helvetica,sans-Serif" font-size="14.00">currency</text>
<text text-anchor="start" x="4750" y="-6530.8" font-family="Helvetica,sans-Serif" font-size="14.00"> </text>
<text text-anchor="start" x="4765" y="-6530.8" font-family="Helvetica,sans-Serif" font-size="14.00">text not null</text>
<polygon fill="none" stroke="#888888" points="4616.5,-6524.5 4616.5,-6659.5 4873.5,-6659.5 4873.5,-6524.5 4616.5,-6524.5" />
</g> <!-- premiumentry_b0060b91&#45;&gt;premiumlist_7c3ea68b -->
<g id="edge36" class="edge">
<title>
premiumentry_b0060b91:w-&gt;premiumlist_7c3ea68b:e
</title>
<path fill="none" stroke="black" d="M5271.77,-6612C5105.08,-6612 5054.58,-6612 4884.07,-6612" />
<polygon fill="black" stroke="black" points="5280,-6612 5290,-6616.5 5285,-6612 5290,-6612 5290,-6612 5290,-6612 5285,-6612 5290,-6607.5 5280,-6612 5280,-6612" />
<ellipse fill="none" stroke="black" cx="5276" cy="-6612" rx="4" ry="4" />
<polygon fill="black" stroke="black" points="4875,-6617 4875,-6607 4877,-6607 4877,-6617 4875,-6617" />
<polyline fill="none" stroke="black" points="4874,-6612 4879,-6612 " />
<polygon fill="black" stroke="black" points="4880,-6617 4880,-6607 4882,-6607 4882,-6617 4880,-6617" />
<polyline fill="none" stroke="black" points="4879,-6612 4884,-6612 " />
<text text-anchor="start" x="4970.5" y="-6615.8" font-family="Helvetica,sans-Serif" font-size="14.00">fko0gw90lpo1tuee56l0nb6y6g5</text>
<path fill="none" stroke="black" d="M5271.77,-6630C5105.08,-6630 5054.58,-6630 4884.07,-6630" />
<polygon fill="black" stroke="black" points="5280,-6630 5290,-6634.5 5285,-6630 5290,-6630 5290,-6630 5290,-6630 5285,-6630 5290,-6625.5 5280,-6630 5280,-6630" />
<ellipse fill="none" stroke="black" cx="5276" cy="-6630" rx="4" ry="4" />
<polygon fill="black" stroke="black" points="4875,-6635 4875,-6625 4877,-6625 4877,-6635 4875,-6635" />
<polyline fill="none" stroke="black" points="4874,-6630 4879,-6630 " />
<polygon fill="black" stroke="black" points="4880,-6635 4880,-6625 4882,-6625 4882,-6635 4880,-6635" />
<polyline fill="none" stroke="black" points="4879,-6630 4884,-6630 " />
<text text-anchor="start" x="4970.5" y="-6633.8" font-family="Helvetica,sans-Serif" font-size="14.00">fko0gw90lpo1tuee56l0nb6y6g5</text>
</g> <!-- rderevision_83396864 -->
<g id="node35" class="node">
<title>
rderevision_83396864
</title>
<polygon fill="#e9c2f2" stroke="transparent" points="5327,-6763 5327,-6782 5470,-6782 5470,-6763 5327,-6763" />
<text text-anchor="start" x="5329" y="-6769.8" font-family="Helvetica,sans-Serif" font-weight="bold" font-style="italic" font-size="14.00">public."RdeRevision"</text>
<polygon fill="#e9c2f2" stroke="transparent" points="5470,-6763 5470,-6782 5549,-6782 5549,-6763 5470,-6763" />
<text text-anchor="start" x="5510" y="-6768.8" font-family="Helvetica,sans-Serif" font-size="14.00">[table]</text>
<text text-anchor="start" x="5329" y="-6750.8" font-family="Helvetica,sans-Serif" font-weight="bold" font-style="italic" font-size="14.00">tld</text>
<text text-anchor="start" x="5455" y="-6749.8" font-family="Helvetica,sans-Serif" font-size="14.00"> </text>
<text text-anchor="start" x="5472" y="-6749.8" font-family="Helvetica,sans-Serif" font-size="14.00">text not null</text>
<text text-anchor="start" x="5329" y="-6731.8" font-family="Helvetica,sans-Serif" font-weight="bold" font-style="italic" font-size="14.00">mode</text>
<text text-anchor="start" x="5455" y="-6730.8" font-family="Helvetica,sans-Serif" font-size="14.00"> </text>
<text text-anchor="start" x="5472" y="-6730.8" font-family="Helvetica,sans-Serif" font-size="14.00">text not null</text>
<text text-anchor="start" x="5329" y="-6712.8" font-family="Helvetica,sans-Serif" font-weight="bold" font-style="italic" font-size="14.00">"date"</text>
<text text-anchor="start" x="5455" y="-6711.8" font-family="Helvetica,sans-Serif" font-size="14.00"> </text>
<text text-anchor="start" x="5472" y="-6711.8" font-family="Helvetica,sans-Serif" font-size="14.00">date not null</text>
<text text-anchor="start" x="5329" y="-6692.8" font-family="Helvetica,sans-Serif" font-size="14.00">update_timestamp</text>
<text text-anchor="start" x="5455" y="-6692.8" font-family="Helvetica,sans-Serif" font-size="14.00"> </text>
<text text-anchor="start" x="5472" y="-6692.8" font-family="Helvetica,sans-Serif" font-size="14.00">timestamptz</text>
<text text-anchor="start" x="5329" y="-6673.8" font-family="Helvetica,sans-Serif" font-size="14.00">revision</text>
<text text-anchor="start" x="5455" y="-6673.8" font-family="Helvetica,sans-Serif" font-size="14.00"> </text>
<text text-anchor="start" x="5472" y="-6673.8" font-family="Helvetica,sans-Serif" font-size="14.00">int4 not null</text>
<polygon fill="none" stroke="#888888" points="5326,-6667 5326,-6783 5550,-6783 5550,-6667 5326,-6667" />
<polygon fill="#e9c2f2" stroke="transparent" points="5327,-6781 5327,-6800 5470,-6800 5470,-6781 5327,-6781" />
<text text-anchor="start" x="5329" y="-6787.8" font-family="Helvetica,sans-Serif" font-weight="bold" font-style="italic" font-size="14.00">public."RdeRevision"</text>
<polygon fill="#e9c2f2" stroke="transparent" points="5470,-6781 5470,-6800 5549,-6800 5549,-6781 5470,-6781" />
<text text-anchor="start" x="5510" y="-6786.8" font-family="Helvetica,sans-Serif" font-size="14.00">[table]</text>
<text text-anchor="start" x="5329" y="-6768.8" font-family="Helvetica,sans-Serif" font-weight="bold" font-style="italic" font-size="14.00">tld</text>
<text text-anchor="start" x="5455" y="-6767.8" font-family="Helvetica,sans-Serif" font-size="14.00"> </text>
<text text-anchor="start" x="5472" y="-6767.8" font-family="Helvetica,sans-Serif" font-size="14.00">text not null</text>
<text text-anchor="start" x="5329" y="-6749.8" font-family="Helvetica,sans-Serif" font-weight="bold" font-style="italic" font-size="14.00">mode</text>
<text text-anchor="start" x="5455" y="-6748.8" font-family="Helvetica,sans-Serif" font-size="14.00"> </text>
<text text-anchor="start" x="5472" y="-6748.8" font-family="Helvetica,sans-Serif" font-size="14.00">text not null</text>
<text text-anchor="start" x="5329" y="-6730.8" font-family="Helvetica,sans-Serif" font-weight="bold" font-style="italic" font-size="14.00">"date"</text>
<text text-anchor="start" x="5455" y="-6729.8" font-family="Helvetica,sans-Serif" font-size="14.00"> </text>
<text text-anchor="start" x="5472" y="-6729.8" font-family="Helvetica,sans-Serif" font-size="14.00">date not null</text>
<text text-anchor="start" x="5329" y="-6710.8" font-family="Helvetica,sans-Serif" font-size="14.00">update_timestamp</text>
<text text-anchor="start" x="5455" y="-6710.8" font-family="Helvetica,sans-Serif" font-size="14.00"> </text>
<text text-anchor="start" x="5472" y="-6710.8" font-family="Helvetica,sans-Serif" font-size="14.00">timestamptz</text>
<text text-anchor="start" x="5329" y="-6691.8" font-family="Helvetica,sans-Serif" font-size="14.00">revision</text>
<text text-anchor="start" x="5455" y="-6691.8" font-family="Helvetica,sans-Serif" font-size="14.00"> </text>
<text text-anchor="start" x="5472" y="-6691.8" font-family="Helvetica,sans-Serif" font-size="14.00">int4 not null</text>
<polygon fill="none" stroke="#888888" points="5326,-6685 5326,-6801 5550,-6801 5550,-6685 5326,-6685" />
</g> <!-- registrarpoc_ab47054d -->
<g id="node37" class="node">
<title>
@@ -3623,300 +3626,300 @@ td.section {
<title>
registrylock_ac88663e
</title>
<polygon fill="#e9c2f2" stroke="transparent" points="5296,-7095 5296,-7114 5455,-7114 5455,-7095 5296,-7095" />
<text text-anchor="start" x="5298" y="-7101.8" font-family="Helvetica,sans-Serif" font-weight="bold" font-style="italic" font-size="14.00">public."RegistryLock"</text>
<polygon fill="#e9c2f2" stroke="transparent" points="5455,-7095 5455,-7114 5581,-7114 5581,-7095 5455,-7095" />
<text text-anchor="start" x="5542" y="-7100.8" font-family="Helvetica,sans-Serif" font-size="14.00">[table]</text>
<text text-anchor="start" x="5298" y="-7082.8" font-family="Helvetica,sans-Serif" font-weight="bold" font-style="italic" font-size="14.00">revision_id</text>
<text text-anchor="start" x="5449" y="-7081.8" font-family="Helvetica,sans-Serif" font-size="14.00"> </text>
<text text-anchor="start" x="5457" y="-7081.8" font-family="Helvetica,sans-Serif" font-size="14.00">bigserial not null</text>
<text text-anchor="start" x="5449" y="-7062.8" font-family="Helvetica,sans-Serif" font-size="14.00"> </text>
<text text-anchor="start" x="5457" y="-7062.8" font-family="Helvetica,sans-Serif" font-size="14.00">auto-incremented</text>
<text text-anchor="start" x="5298" y="-7043.8" font-family="Helvetica,sans-Serif" font-size="14.00">lock_completion_time</text>
<text text-anchor="start" x="5449" y="-7043.8" font-family="Helvetica,sans-Serif" font-size="14.00"> </text>
<text text-anchor="start" x="5457" y="-7043.8" font-family="Helvetica,sans-Serif" font-size="14.00">timestamptz</text>
<text text-anchor="start" x="5298" y="-7024.8" font-family="Helvetica,sans-Serif" font-size="14.00">lock_request_time</text>
<text text-anchor="start" x="5449" y="-7024.8" font-family="Helvetica,sans-Serif" font-size="14.00"> </text>
<text text-anchor="start" x="5457" y="-7024.8" font-family="Helvetica,sans-Serif" font-size="14.00">timestamptz not null</text>
<text text-anchor="start" x="5298" y="-7005.8" font-family="Helvetica,sans-Serif" font-size="14.00">domain_name</text>
<text text-anchor="start" x="5449" y="-7005.8" font-family="Helvetica,sans-Serif" font-size="14.00"> </text>
<text text-anchor="start" x="5457" y="-7005.8" font-family="Helvetica,sans-Serif" font-size="14.00">text not null</text>
<text text-anchor="start" x="5298" y="-6986.8" font-family="Helvetica,sans-Serif" font-size="14.00">is_superuser</text>
<text text-anchor="start" x="5449" y="-6986.8" font-family="Helvetica,sans-Serif" font-size="14.00"> </text>
<text text-anchor="start" x="5457" y="-6986.8" font-family="Helvetica,sans-Serif" font-size="14.00">bool not null</text>
<text text-anchor="start" x="5298" y="-6967.8" font-family="Helvetica,sans-Serif" font-size="14.00">registrar_id</text>
<text text-anchor="start" x="5449" y="-6967.8" font-family="Helvetica,sans-Serif" font-size="14.00"> </text>
<text text-anchor="start" x="5457" y="-6967.8" font-family="Helvetica,sans-Serif" font-size="14.00">text not null</text>
<text text-anchor="start" x="5298" y="-6948.8" font-family="Helvetica,sans-Serif" font-size="14.00">registrar_poc_id</text>
<text text-anchor="start" x="5449" y="-6948.8" font-family="Helvetica,sans-Serif" font-size="14.00"> </text>
<text text-anchor="start" x="5457" y="-6948.8" font-family="Helvetica,sans-Serif" font-size="14.00">text</text>
<text text-anchor="start" x="5298" y="-6929.8" font-family="Helvetica,sans-Serif" font-size="14.00">repo_id</text>
<text text-anchor="start" x="5449" y="-6929.8" font-family="Helvetica,sans-Serif" font-size="14.00"> </text>
<text text-anchor="start" x="5457" y="-6929.8" font-family="Helvetica,sans-Serif" font-size="14.00">text not null</text>
<text text-anchor="start" x="5298" y="-6910.8" font-family="Helvetica,sans-Serif" font-size="14.00">verification_code</text>
<text text-anchor="start" x="5449" y="-6910.8" font-family="Helvetica,sans-Serif" font-size="14.00"> </text>
<text text-anchor="start" x="5457" y="-6910.8" font-family="Helvetica,sans-Serif" font-size="14.00">text not null</text>
<text text-anchor="start" x="5298" y="-6891.8" font-family="Helvetica,sans-Serif" font-size="14.00">unlock_request_time</text>
<text text-anchor="start" x="5449" y="-6891.8" font-family="Helvetica,sans-Serif" font-size="14.00"> </text>
<text text-anchor="start" x="5457" y="-6891.8" font-family="Helvetica,sans-Serif" font-size="14.00">timestamptz</text>
<text text-anchor="start" x="5298" y="-6872.8" font-family="Helvetica,sans-Serif" font-size="14.00">unlock_completion_time</text>
<text text-anchor="start" x="5449" y="-6872.8" font-family="Helvetica,sans-Serif" font-size="14.00"> </text>
<text text-anchor="start" x="5457" y="-6872.8" font-family="Helvetica,sans-Serif" font-size="14.00">timestamptz</text>
<text text-anchor="start" x="5298" y="-6853.8" font-family="Helvetica,sans-Serif" font-size="14.00">last_update_time</text>
<text text-anchor="start" x="5449" y="-6853.8" font-family="Helvetica,sans-Serif" font-size="14.00"> </text>
<text text-anchor="start" x="5457" y="-6853.8" font-family="Helvetica,sans-Serif" font-size="14.00">timestamptz not null</text>
<text text-anchor="start" x="5298" y="-6834.8" font-family="Helvetica,sans-Serif" font-size="14.00">relock_revision_id</text>
<text text-anchor="start" x="5449" y="-6834.8" font-family="Helvetica,sans-Serif" font-size="14.00"> </text>
<text text-anchor="start" x="5457" y="-6834.8" font-family="Helvetica,sans-Serif" font-size="14.00">int8</text>
<text text-anchor="start" x="5298" y="-6815.8" font-family="Helvetica,sans-Serif" font-size="14.00">relock_duration</text>
<text text-anchor="start" x="5449" y="-6815.8" font-family="Helvetica,sans-Serif" font-size="14.00"> </text>
<text text-anchor="start" x="5457" y="-6815.8" font-family="Helvetica,sans-Serif" font-size="14.00">interval</text>
<polygon fill="none" stroke="#888888" points="5294.5,-6809 5294.5,-7115 5581.5,-7115 5581.5,-6809 5294.5,-6809" />
<polygon fill="#e9c2f2" stroke="transparent" points="5296,-7113 5296,-7132 5455,-7132 5455,-7113 5296,-7113" />
<text text-anchor="start" x="5298" y="-7119.8" font-family="Helvetica,sans-Serif" font-weight="bold" font-style="italic" font-size="14.00">public."RegistryLock"</text>
<polygon fill="#e9c2f2" stroke="transparent" points="5455,-7113 5455,-7132 5581,-7132 5581,-7113 5455,-7113" />
<text text-anchor="start" x="5542" y="-7118.8" font-family="Helvetica,sans-Serif" font-size="14.00">[table]</text>
<text text-anchor="start" x="5298" y="-7100.8" font-family="Helvetica,sans-Serif" font-weight="bold" font-style="italic" font-size="14.00">revision_id</text>
<text text-anchor="start" x="5449" y="-7099.8" font-family="Helvetica,sans-Serif" font-size="14.00"> </text>
<text text-anchor="start" x="5457" y="-7099.8" font-family="Helvetica,sans-Serif" font-size="14.00">bigserial not null</text>
<text text-anchor="start" x="5449" y="-7080.8" font-family="Helvetica,sans-Serif" font-size="14.00"> </text>
<text text-anchor="start" x="5457" y="-7080.8" font-family="Helvetica,sans-Serif" font-size="14.00">auto-incremented</text>
<text text-anchor="start" x="5298" y="-7061.8" font-family="Helvetica,sans-Serif" font-size="14.00">lock_completion_time</text>
<text text-anchor="start" x="5449" y="-7061.8" font-family="Helvetica,sans-Serif" font-size="14.00"> </text>
<text text-anchor="start" x="5457" y="-7061.8" font-family="Helvetica,sans-Serif" font-size="14.00">timestamptz</text>
<text text-anchor="start" x="5298" y="-7042.8" font-family="Helvetica,sans-Serif" font-size="14.00">lock_request_time</text>
<text text-anchor="start" x="5449" y="-7042.8" font-family="Helvetica,sans-Serif" font-size="14.00"> </text>
<text text-anchor="start" x="5457" y="-7042.8" font-family="Helvetica,sans-Serif" font-size="14.00">timestamptz not null</text>
<text text-anchor="start" x="5298" y="-7023.8" font-family="Helvetica,sans-Serif" font-size="14.00">domain_name</text>
<text text-anchor="start" x="5449" y="-7023.8" font-family="Helvetica,sans-Serif" font-size="14.00"> </text>
<text text-anchor="start" x="5457" y="-7023.8" font-family="Helvetica,sans-Serif" font-size="14.00">text not null</text>
<text text-anchor="start" x="5298" y="-7004.8" font-family="Helvetica,sans-Serif" font-size="14.00">is_superuser</text>
<text text-anchor="start" x="5449" y="-7004.8" font-family="Helvetica,sans-Serif" font-size="14.00"> </text>
<text text-anchor="start" x="5457" y="-7004.8" font-family="Helvetica,sans-Serif" font-size="14.00">bool not null</text>
<text text-anchor="start" x="5298" y="-6985.8" font-family="Helvetica,sans-Serif" font-size="14.00">registrar_id</text>
<text text-anchor="start" x="5449" y="-6985.8" font-family="Helvetica,sans-Serif" font-size="14.00"> </text>
<text text-anchor="start" x="5457" y="-6985.8" font-family="Helvetica,sans-Serif" font-size="14.00">text not null</text>
<text text-anchor="start" x="5298" y="-6966.8" font-family="Helvetica,sans-Serif" font-size="14.00">registrar_poc_id</text>
<text text-anchor="start" x="5449" y="-6966.8" font-family="Helvetica,sans-Serif" font-size="14.00"> </text>
<text text-anchor="start" x="5457" y="-6966.8" font-family="Helvetica,sans-Serif" font-size="14.00">text</text>
<text text-anchor="start" x="5298" y="-6947.8" font-family="Helvetica,sans-Serif" font-size="14.00">repo_id</text>
<text text-anchor="start" x="5449" y="-6947.8" font-family="Helvetica,sans-Serif" font-size="14.00"> </text>
<text text-anchor="start" x="5457" y="-6947.8" font-family="Helvetica,sans-Serif" font-size="14.00">text not null</text>
<text text-anchor="start" x="5298" y="-6928.8" font-family="Helvetica,sans-Serif" font-size="14.00">verification_code</text>
<text text-anchor="start" x="5449" y="-6928.8" font-family="Helvetica,sans-Serif" font-size="14.00"> </text>
<text text-anchor="start" x="5457" y="-6928.8" font-family="Helvetica,sans-Serif" font-size="14.00">text not null</text>
<text text-anchor="start" x="5298" y="-6909.8" font-family="Helvetica,sans-Serif" font-size="14.00">unlock_request_time</text>
<text text-anchor="start" x="5449" y="-6909.8" font-family="Helvetica,sans-Serif" font-size="14.00"> </text>
<text text-anchor="start" x="5457" y="-6909.8" font-family="Helvetica,sans-Serif" font-size="14.00">timestamptz</text>
<text text-anchor="start" x="5298" y="-6890.8" font-family="Helvetica,sans-Serif" font-size="14.00">unlock_completion_time</text>
<text text-anchor="start" x="5449" y="-6890.8" font-family="Helvetica,sans-Serif" font-size="14.00"> </text>
<text text-anchor="start" x="5457" y="-6890.8" font-family="Helvetica,sans-Serif" font-size="14.00">timestamptz</text>
<text text-anchor="start" x="5298" y="-6871.8" font-family="Helvetica,sans-Serif" font-size="14.00">last_update_time</text>
<text text-anchor="start" x="5449" y="-6871.8" font-family="Helvetica,sans-Serif" font-size="14.00"> </text>
<text text-anchor="start" x="5457" y="-6871.8" font-family="Helvetica,sans-Serif" font-size="14.00">timestamptz not null</text>
<text text-anchor="start" x="5298" y="-6852.8" font-family="Helvetica,sans-Serif" font-size="14.00">relock_revision_id</text>
<text text-anchor="start" x="5449" y="-6852.8" font-family="Helvetica,sans-Serif" font-size="14.00"> </text>
<text text-anchor="start" x="5457" y="-6852.8" font-family="Helvetica,sans-Serif" font-size="14.00">int8</text>
<text text-anchor="start" x="5298" y="-6833.8" font-family="Helvetica,sans-Serif" font-size="14.00">relock_duration</text>
<text text-anchor="start" x="5449" y="-6833.8" font-family="Helvetica,sans-Serif" font-size="14.00"> </text>
<text text-anchor="start" x="5457" y="-6833.8" font-family="Helvetica,sans-Serif" font-size="14.00">interval</text>
<polygon fill="none" stroke="#888888" points="5294.5,-6827 5294.5,-7133 5581.5,-7133 5581.5,-6827 5294.5,-6827" />
</g> <!-- registrylock_ac88663e&#45;&gt;registrylock_ac88663e -->
<g id="edge64" class="edge">
<title>
registrylock_ac88663e:w-&gt;registrylock_ac88663e:e
</title>
<path fill="none" stroke="black" d="M5281.52,-6849.14C5203.21,-6921.94 5215.41,-7137 5438.5,-7137 5666.43,-7137 5674.22,-7125.81 5590.25,-7089.9" />
<polygon fill="black" stroke="black" points="5288.07,-6844.1 5298.74,-6841.57 5292.04,-6841.05 5296,-6838 5296,-6838 5296,-6838 5292.04,-6841.05 5293.26,-6834.43 5288.07,-6844.1 5288.07,-6844.1" />
<ellipse fill="none" stroke="black" cx="5284.9" cy="-6846.54" rx="4" ry="4" />
<polygon fill="black" stroke="black" points="5579.98,-7091 5583.87,-7081.78 5585.71,-7082.56 5581.82,-7091.77 5579.98,-7091" />
<polyline fill="none" stroke="black" points="5581,-7086 5585.61,-7087.94 " />
<polygon fill="black" stroke="black" points="5584.58,-7092.94 5588.47,-7083.73 5590.31,-7084.5 5586.43,-7093.72 5584.58,-7092.94" />
<polyline fill="none" stroke="black" points="5585.61,-7087.94 5590.21,-7089.89 " />
<text text-anchor="start" x="5356.5" y="-7140.8" font-family="Helvetica,sans-Serif" font-size="14.00">fk2lhcwpxlnqijr96irylrh1707</text>
<path fill="none" stroke="black" d="M5281.52,-6867.14C5203.21,-6939.94 5215.41,-7155 5438.5,-7155 5666.43,-7155 5674.22,-7143.81 5590.25,-7107.9" />
<polygon fill="black" stroke="black" points="5288.07,-6862.1 5298.74,-6859.57 5292.04,-6859.05 5296,-6856 5296,-6856 5296,-6856 5292.04,-6859.05 5293.26,-6852.43 5288.07,-6862.1 5288.07,-6862.1" />
<ellipse fill="none" stroke="black" cx="5284.9" cy="-6864.54" rx="4" ry="4" />
<polygon fill="black" stroke="black" points="5579.98,-7109 5583.87,-7099.78 5585.71,-7100.56 5581.82,-7109.77 5579.98,-7109" />
<polyline fill="none" stroke="black" points="5581,-7104 5585.61,-7105.94 " />
<polygon fill="black" stroke="black" points="5584.58,-7110.94 5588.47,-7101.73 5590.31,-7102.5 5586.43,-7111.72 5584.58,-7110.94" />
<polyline fill="none" stroke="black" points="5585.61,-7105.94 5590.21,-7107.89 " />
<text text-anchor="start" x="5356.5" y="-7158.8" font-family="Helvetica,sans-Serif" font-size="14.00">fk2lhcwpxlnqijr96irylrh1707</text>
</g> <!-- reservedentry_1a7b8520 -->
<g id="node41" class="node">
<title>
reservedentry_1a7b8520
</title>
<polygon fill="#e9c2f2" stroke="transparent" points="5323,-7251 5323,-7270 5480,-7270 5480,-7251 5323,-7251" />
<text text-anchor="start" x="5325" y="-7257.8" font-family="Helvetica,sans-Serif" font-weight="bold" font-style="italic" font-size="14.00">public."ReservedEntry"</text>
<polygon fill="#e9c2f2" stroke="transparent" points="5480,-7251 5480,-7270 5554,-7270 5554,-7251 5480,-7251" />
<text text-anchor="start" x="5515" y="-7256.8" font-family="Helvetica,sans-Serif" font-size="14.00">[table]</text>
<text text-anchor="start" x="5325" y="-7238.8" font-family="Helvetica,sans-Serif" font-weight="bold" font-style="italic" font-size="14.00">revision_id</text>
<text text-anchor="start" x="5451" y="-7237.8" font-family="Helvetica,sans-Serif" font-size="14.00"> </text>
<text text-anchor="start" x="5482" y="-7237.8" font-family="Helvetica,sans-Serif" font-size="14.00">int8 not null</text>
<text text-anchor="start" x="5325" y="-7218.8" font-family="Helvetica,sans-Serif" font-size="14.00">comment</text>
<text text-anchor="start" x="5451" y="-7218.8" font-family="Helvetica,sans-Serif" font-size="14.00"> </text>
<text text-anchor="start" x="5482" y="-7218.8" font-family="Helvetica,sans-Serif" font-size="14.00">text</text>
<text text-anchor="start" x="5325" y="-7199.8" font-family="Helvetica,sans-Serif" font-size="14.00">reservation_type</text>
<text text-anchor="start" x="5451" y="-7199.8" font-family="Helvetica,sans-Serif" font-size="14.00"> </text>
<text text-anchor="start" x="5482" y="-7199.8" font-family="Helvetica,sans-Serif" font-size="14.00">int4 not null</text>
<text text-anchor="start" x="5325" y="-7181.8" font-family="Helvetica,sans-Serif" font-weight="bold" font-style="italic" font-size="14.00">domain_label</text>
<text text-anchor="start" x="5451" y="-7180.8" font-family="Helvetica,sans-Serif" font-size="14.00"> </text>
<text text-anchor="start" x="5482" y="-7180.8" font-family="Helvetica,sans-Serif" font-size="14.00">text not null</text>
<polygon fill="none" stroke="#888888" points="5321.5,-7174.5 5321.5,-7271.5 5554.5,-7271.5 5554.5,-7174.5 5321.5,-7174.5" />
<polygon fill="#e9c2f2" stroke="transparent" points="5323,-7269 5323,-7288 5480,-7288 5480,-7269 5323,-7269" />
<text text-anchor="start" x="5325" y="-7275.8" font-family="Helvetica,sans-Serif" font-weight="bold" font-style="italic" font-size="14.00">public."ReservedEntry"</text>
<polygon fill="#e9c2f2" stroke="transparent" points="5480,-7269 5480,-7288 5554,-7288 5554,-7269 5480,-7269" />
<text text-anchor="start" x="5515" y="-7274.8" font-family="Helvetica,sans-Serif" font-size="14.00">[table]</text>
<text text-anchor="start" x="5325" y="-7256.8" font-family="Helvetica,sans-Serif" font-weight="bold" font-style="italic" font-size="14.00">revision_id</text>
<text text-anchor="start" x="5451" y="-7255.8" font-family="Helvetica,sans-Serif" font-size="14.00"> </text>
<text text-anchor="start" x="5482" y="-7255.8" font-family="Helvetica,sans-Serif" font-size="14.00">int8 not null</text>
<text text-anchor="start" x="5325" y="-7236.8" font-family="Helvetica,sans-Serif" font-size="14.00">comment</text>
<text text-anchor="start" x="5451" y="-7236.8" font-family="Helvetica,sans-Serif" font-size="14.00"> </text>
<text text-anchor="start" x="5482" y="-7236.8" font-family="Helvetica,sans-Serif" font-size="14.00">text</text>
<text text-anchor="start" x="5325" y="-7217.8" font-family="Helvetica,sans-Serif" font-size="14.00">reservation_type</text>
<text text-anchor="start" x="5451" y="-7217.8" font-family="Helvetica,sans-Serif" font-size="14.00"> </text>
<text text-anchor="start" x="5482" y="-7217.8" font-family="Helvetica,sans-Serif" font-size="14.00">int4 not null</text>
<text text-anchor="start" x="5325" y="-7199.8" font-family="Helvetica,sans-Serif" font-weight="bold" font-style="italic" font-size="14.00">domain_label</text>
<text text-anchor="start" x="5451" y="-7198.8" font-family="Helvetica,sans-Serif" font-size="14.00"> </text>
<text text-anchor="start" x="5482" y="-7198.8" font-family="Helvetica,sans-Serif" font-size="14.00">text not null</text>
<polygon fill="none" stroke="#888888" points="5321.5,-7192.5 5321.5,-7289.5 5554.5,-7289.5 5554.5,-7192.5 5321.5,-7192.5" />
</g> <!-- reservedlist_b97c3f1c -->
<g id="node42" class="node">
<title>
reservedlist_b97c3f1c
</title>
<polygon fill="#e9c2f2" stroke="transparent" points="4609,-7251 4609,-7270 4755,-7270 4755,-7251 4609,-7251" />
<text text-anchor="start" x="4611" y="-7257.8" font-family="Helvetica,sans-Serif" font-weight="bold" font-style="italic" font-size="14.00">public."ReservedList"</text>
<polygon fill="#e9c2f2" stroke="transparent" points="4755,-7251 4755,-7270 4881,-7270 4881,-7251 4755,-7251" />
<text text-anchor="start" x="4842" y="-7256.8" font-family="Helvetica,sans-Serif" font-size="14.00">[table]</text>
<text text-anchor="start" x="4611" y="-7238.8" font-family="Helvetica,sans-Serif" font-weight="bold" font-style="italic" font-size="14.00">revision_id</text>
<text text-anchor="start" x="4742" y="-7237.8" font-family="Helvetica,sans-Serif" font-size="14.00"> </text>
<text text-anchor="start" x="4757" y="-7237.8" font-family="Helvetica,sans-Serif" font-size="14.00">bigserial not null</text>
<text text-anchor="start" x="4742" y="-7218.8" font-family="Helvetica,sans-Serif" font-size="14.00"> </text>
<text text-anchor="start" x="4757" y="-7218.8" font-family="Helvetica,sans-Serif" font-size="14.00">auto-incremented</text>
<text text-anchor="start" x="4611" y="-7199.8" font-family="Helvetica,sans-Serif" font-size="14.00">creation_timestamp</text>
<text text-anchor="start" x="4742" y="-7199.8" font-family="Helvetica,sans-Serif" font-size="14.00"> </text>
<text text-anchor="start" x="4757" y="-7199.8" font-family="Helvetica,sans-Serif" font-size="14.00">timestamptz not null</text>
<text text-anchor="start" x="4611" y="-7180.8" font-family="Helvetica,sans-Serif" font-size="14.00">name</text>
<text text-anchor="start" x="4742" y="-7180.8" font-family="Helvetica,sans-Serif" font-size="14.00"> </text>
<text text-anchor="start" x="4757" y="-7180.8" font-family="Helvetica,sans-Serif" font-size="14.00">text not null</text>
<polygon fill="none" stroke="#888888" points="4608,-7174.5 4608,-7271.5 4882,-7271.5 4882,-7174.5 4608,-7174.5" />
<polygon fill="#e9c2f2" stroke="transparent" points="4609,-7269 4609,-7288 4755,-7288 4755,-7269 4609,-7269" />
<text text-anchor="start" x="4611" y="-7275.8" font-family="Helvetica,sans-Serif" font-weight="bold" font-style="italic" font-size="14.00">public."ReservedList"</text>
<polygon fill="#e9c2f2" stroke="transparent" points="4755,-7269 4755,-7288 4881,-7288 4881,-7269 4755,-7269" />
<text text-anchor="start" x="4842" y="-7274.8" font-family="Helvetica,sans-Serif" font-size="14.00">[table]</text>
<text text-anchor="start" x="4611" y="-7256.8" font-family="Helvetica,sans-Serif" font-weight="bold" font-style="italic" font-size="14.00">revision_id</text>
<text text-anchor="start" x="4742" y="-7255.8" font-family="Helvetica,sans-Serif" font-size="14.00"> </text>
<text text-anchor="start" x="4757" y="-7255.8" font-family="Helvetica,sans-Serif" font-size="14.00">bigserial not null</text>
<text text-anchor="start" x="4742" y="-7236.8" font-family="Helvetica,sans-Serif" font-size="14.00"> </text>
<text text-anchor="start" x="4757" y="-7236.8" font-family="Helvetica,sans-Serif" font-size="14.00">auto-incremented</text>
<text text-anchor="start" x="4611" y="-7217.8" font-family="Helvetica,sans-Serif" font-size="14.00">creation_timestamp</text>
<text text-anchor="start" x="4742" y="-7217.8" font-family="Helvetica,sans-Serif" font-size="14.00"> </text>
<text text-anchor="start" x="4757" y="-7217.8" font-family="Helvetica,sans-Serif" font-size="14.00">timestamptz not null</text>
<text text-anchor="start" x="4611" y="-7198.8" font-family="Helvetica,sans-Serif" font-size="14.00">name</text>
<text text-anchor="start" x="4742" y="-7198.8" font-family="Helvetica,sans-Serif" font-size="14.00"> </text>
<text text-anchor="start" x="4757" y="-7198.8" font-family="Helvetica,sans-Serif" font-size="14.00">text not null</text>
<polygon fill="none" stroke="#888888" points="4608,-7192.5 4608,-7289.5 4882,-7289.5 4882,-7192.5 4608,-7192.5" />
</g> <!-- reservedentry_1a7b8520&#45;&gt;reservedlist_b97c3f1c -->
<g id="edge65" class="edge">
<title>
reservedentry_1a7b8520:w-&gt;reservedlist_b97c3f1c:e
</title>
<path fill="none" stroke="black" d="M5303.81,-7242C5126.46,-7242 5073.26,-7242 4892.13,-7242" />
<polygon fill="black" stroke="black" points="5312,-7242 5322,-7246.5 5317,-7242 5322,-7242 5322,-7242 5322,-7242 5317,-7242 5322,-7237.5 5312,-7242 5312,-7242" />
<ellipse fill="none" stroke="black" cx="5308" cy="-7242" rx="4" ry="4" />
<polygon fill="black" stroke="black" points="4883,-7247 4883,-7237 4885,-7237 4885,-7247 4883,-7247" />
<polyline fill="none" stroke="black" points="4882,-7242 4887,-7242 " />
<polygon fill="black" stroke="black" points="4888,-7247 4888,-7237 4890,-7237 4890,-7247 4888,-7247" />
<polyline fill="none" stroke="black" points="4887,-7242 4892,-7242 " />
<text text-anchor="start" x="4972" y="-7245.8" font-family="Helvetica,sans-Serif" font-size="14.00">fkgq03rk0bt1hb915dnyvd3vnfc</text>
<path fill="none" stroke="black" d="M5303.81,-7260C5126.46,-7260 5073.26,-7260 4892.13,-7260" />
<polygon fill="black" stroke="black" points="5312,-7260 5322,-7264.5 5317,-7260 5322,-7260 5322,-7260 5322,-7260 5317,-7260 5322,-7255.5 5312,-7260 5312,-7260" />
<ellipse fill="none" stroke="black" cx="5308" cy="-7260" rx="4" ry="4" />
<polygon fill="black" stroke="black" points="4883,-7265 4883,-7255 4885,-7255 4885,-7265 4883,-7265" />
<polyline fill="none" stroke="black" points="4882,-7260 4887,-7260 " />
<polygon fill="black" stroke="black" points="4888,-7265 4888,-7255 4890,-7255 4890,-7265 4888,-7265" />
<polyline fill="none" stroke="black" points="4887,-7260 4892,-7260 " />
<text text-anchor="start" x="4972" y="-7263.8" font-family="Helvetica,sans-Serif" font-size="14.00">fkgq03rk0bt1hb915dnyvd3vnfc</text>
</g> <!-- serversecret_6cc90f09 -->
<g id="node43" class="node">
<title>
serversecret_6cc90f09
</title>
<polygon fill="#e9c2f2" stroke="transparent" points="5327,-7336 5327,-7355 5472,-7355 5472,-7336 5327,-7336" />
<text text-anchor="start" x="5329" y="-7342.8" font-family="Helvetica,sans-Serif" font-weight="bold" font-style="italic" font-size="14.00">public."ServerSecret"</text>
<polygon fill="#e9c2f2" stroke="transparent" points="5472,-7336 5472,-7355 5549,-7355 5549,-7336 5472,-7336" />
<text text-anchor="start" x="5510" y="-7341.8" font-family="Helvetica,sans-Serif" font-size="14.00">[table]</text>
<text text-anchor="start" x="5329" y="-7322.8" font-family="Helvetica,sans-Serif" font-size="14.00">secret</text>
<text text-anchor="start" x="5418" y="-7322.8" font-family="Helvetica,sans-Serif" font-size="14.00"> </text>
<text text-anchor="start" x="5474" y="-7322.8" font-family="Helvetica,sans-Serif" font-size="14.00">uuid not null</text>
<text text-anchor="start" x="5329" y="-7304.8" font-family="Helvetica,sans-Serif" font-weight="bold" font-style="italic" font-size="14.00">id</text>
<text text-anchor="start" x="5418" y="-7303.8" font-family="Helvetica,sans-Serif" font-size="14.00"> </text>
<text text-anchor="start" x="5474" y="-7303.8" font-family="Helvetica,sans-Serif" font-size="14.00">int8 not null</text>
<polygon fill="none" stroke="#888888" points="5326,-7297.5 5326,-7356.5 5550,-7356.5 5550,-7297.5 5326,-7297.5" />
<polygon fill="#e9c2f2" stroke="transparent" points="5327,-7354 5327,-7373 5472,-7373 5472,-7354 5327,-7354" />
<text text-anchor="start" x="5329" y="-7360.8" font-family="Helvetica,sans-Serif" font-weight="bold" font-style="italic" font-size="14.00">public."ServerSecret"</text>
<polygon fill="#e9c2f2" stroke="transparent" points="5472,-7354 5472,-7373 5549,-7373 5549,-7354 5472,-7354" />
<text text-anchor="start" x="5510" y="-7359.8" font-family="Helvetica,sans-Serif" font-size="14.00">[table]</text>
<text text-anchor="start" x="5329" y="-7340.8" font-family="Helvetica,sans-Serif" font-size="14.00">secret</text>
<text text-anchor="start" x="5418" y="-7340.8" font-family="Helvetica,sans-Serif" font-size="14.00"> </text>
<text text-anchor="start" x="5474" y="-7340.8" font-family="Helvetica,sans-Serif" font-size="14.00">uuid not null</text>
<text text-anchor="start" x="5329" y="-7322.8" font-family="Helvetica,sans-Serif" font-weight="bold" font-style="italic" font-size="14.00">id</text>
<text text-anchor="start" x="5418" y="-7321.8" font-family="Helvetica,sans-Serif" font-size="14.00"> </text>
<text text-anchor="start" x="5474" y="-7321.8" font-family="Helvetica,sans-Serif" font-size="14.00">int8 not null</text>
<polygon fill="none" stroke="#888888" points="5326,-7315.5 5326,-7374.5 5550,-7374.5 5550,-7315.5 5326,-7315.5" />
</g> <!-- signedmarkrevocationentry_99c39721 -->
<g id="node44" class="node">
<title>
signedmarkrevocationentry_99c39721
</title>
<polygon fill="#e9c2f2" stroke="transparent" points="5252,-7441 5252,-7460 5498,-7460 5498,-7441 5252,-7441" />
<text text-anchor="start" x="5254" y="-7447.8" font-family="Helvetica,sans-Serif" font-weight="bold" font-style="italic" font-size="14.00">public."SignedMarkRevocationEntry"</text>
<polygon fill="#e9c2f2" stroke="transparent" points="5498,-7441 5498,-7460 5624,-7460 5624,-7441 5498,-7441" />
<text text-anchor="start" x="5585" y="-7446.8" font-family="Helvetica,sans-Serif" font-size="14.00">[table]</text>
<text text-anchor="start" x="5254" y="-7428.8" font-family="Helvetica,sans-Serif" font-weight="bold" font-style="italic" font-size="14.00">revision_id</text>
<text text-anchor="start" x="5423" y="-7427.8" font-family="Helvetica,sans-Serif" font-size="14.00"> </text>
<text text-anchor="start" x="5500" y="-7427.8" font-family="Helvetica,sans-Serif" font-size="14.00">int8 not null</text>
<text text-anchor="start" x="5254" y="-7408.8" font-family="Helvetica,sans-Serif" font-size="14.00">revocation_time</text>
<text text-anchor="start" x="5423" y="-7408.8" font-family="Helvetica,sans-Serif" font-size="14.00"> </text>
<text text-anchor="start" x="5500" y="-7408.8" font-family="Helvetica,sans-Serif" font-size="14.00">timestamptz not null</text>
<text text-anchor="start" x="5254" y="-7390.8" font-family="Helvetica,sans-Serif" font-weight="bold" font-style="italic" font-size="14.00">smd_id</text>
<text text-anchor="start" x="5423" y="-7389.8" font-family="Helvetica,sans-Serif" font-size="14.00"> </text>
<text text-anchor="start" x="5500" y="-7389.8" font-family="Helvetica,sans-Serif" font-size="14.00">text not null</text>
<polygon fill="none" stroke="#888888" points="5251,-7383 5251,-7461 5625,-7461 5625,-7383 5251,-7383" />
<polygon fill="#e9c2f2" stroke="transparent" points="5252,-7459 5252,-7478 5498,-7478 5498,-7459 5252,-7459" />
<text text-anchor="start" x="5254" y="-7465.8" font-family="Helvetica,sans-Serif" font-weight="bold" font-style="italic" font-size="14.00">public."SignedMarkRevocationEntry"</text>
<polygon fill="#e9c2f2" stroke="transparent" points="5498,-7459 5498,-7478 5624,-7478 5624,-7459 5498,-7459" />
<text text-anchor="start" x="5585" y="-7464.8" font-family="Helvetica,sans-Serif" font-size="14.00">[table]</text>
<text text-anchor="start" x="5254" y="-7446.8" font-family="Helvetica,sans-Serif" font-weight="bold" font-style="italic" font-size="14.00">revision_id</text>
<text text-anchor="start" x="5423" y="-7445.8" font-family="Helvetica,sans-Serif" font-size="14.00"> </text>
<text text-anchor="start" x="5500" y="-7445.8" font-family="Helvetica,sans-Serif" font-size="14.00">int8 not null</text>
<text text-anchor="start" x="5254" y="-7426.8" font-family="Helvetica,sans-Serif" font-size="14.00">revocation_time</text>
<text text-anchor="start" x="5423" y="-7426.8" font-family="Helvetica,sans-Serif" font-size="14.00"> </text>
<text text-anchor="start" x="5500" y="-7426.8" font-family="Helvetica,sans-Serif" font-size="14.00">timestamptz not null</text>
<text text-anchor="start" x="5254" y="-7408.8" font-family="Helvetica,sans-Serif" font-weight="bold" font-style="italic" font-size="14.00">smd_id</text>
<text text-anchor="start" x="5423" y="-7407.8" font-family="Helvetica,sans-Serif" font-size="14.00"> </text>
<text text-anchor="start" x="5500" y="-7407.8" font-family="Helvetica,sans-Serif" font-size="14.00">text not null</text>
<polygon fill="none" stroke="#888888" points="5251,-7401 5251,-7479 5625,-7479 5625,-7401 5251,-7401" />
</g> <!-- signedmarkrevocationlist_c5d968fb -->
<g id="node45" class="node">
<title>
signedmarkrevocationlist_c5d968fb
</title>
<polygon fill="#e9c2f2" stroke="transparent" points="4572,-7441 4572,-7460 4808,-7460 4808,-7441 4572,-7441" />
<text text-anchor="start" x="4574" y="-7447.8" font-family="Helvetica,sans-Serif" font-weight="bold" font-style="italic" font-size="14.00">public."SignedMarkRevocationList"</text>
<polygon fill="#e9c2f2" stroke="transparent" points="4808,-7441 4808,-7460 4918,-7460 4918,-7441 4808,-7441" />
<text text-anchor="start" x="4879" y="-7446.8" font-family="Helvetica,sans-Serif" font-size="14.00">[table]</text>
<text text-anchor="start" x="4574" y="-7428.8" font-family="Helvetica,sans-Serif" font-weight="bold" font-style="italic" font-size="14.00">revision_id</text>
<text text-anchor="start" x="4731" y="-7427.8" font-family="Helvetica,sans-Serif" font-size="14.00"> </text>
<text text-anchor="start" x="4810" y="-7427.8" font-family="Helvetica,sans-Serif" font-size="14.00">bigserial not null</text>
<text text-anchor="start" x="4731" y="-7408.8" font-family="Helvetica,sans-Serif" font-size="14.00"> </text>
<text text-anchor="start" x="4810" y="-7408.8" font-family="Helvetica,sans-Serif" font-size="14.00">auto-incremented</text>
<text text-anchor="start" x="4574" y="-7389.8" font-family="Helvetica,sans-Serif" font-size="14.00">creation_time</text>
<text text-anchor="start" x="4731" y="-7389.8" font-family="Helvetica,sans-Serif" font-size="14.00"> </text>
<text text-anchor="start" x="4810" y="-7389.8" font-family="Helvetica,sans-Serif" font-size="14.00">timestamptz</text>
<polygon fill="none" stroke="#888888" points="4571,-7383 4571,-7461 4919,-7461 4919,-7383 4571,-7383" />
<polygon fill="#e9c2f2" stroke="transparent" points="4572,-7459 4572,-7478 4808,-7478 4808,-7459 4572,-7459" />
<text text-anchor="start" x="4574" y="-7465.8" font-family="Helvetica,sans-Serif" font-weight="bold" font-style="italic" font-size="14.00">public."SignedMarkRevocationList"</text>
<polygon fill="#e9c2f2" stroke="transparent" points="4808,-7459 4808,-7478 4918,-7478 4918,-7459 4808,-7459" />
<text text-anchor="start" x="4879" y="-7464.8" font-family="Helvetica,sans-Serif" font-size="14.00">[table]</text>
<text text-anchor="start" x="4574" y="-7446.8" font-family="Helvetica,sans-Serif" font-weight="bold" font-style="italic" font-size="14.00">revision_id</text>
<text text-anchor="start" x="4731" y="-7445.8" font-family="Helvetica,sans-Serif" font-size="14.00"> </text>
<text text-anchor="start" x="4810" y="-7445.8" font-family="Helvetica,sans-Serif" font-size="14.00">bigserial not null</text>
<text text-anchor="start" x="4731" y="-7426.8" font-family="Helvetica,sans-Serif" font-size="14.00"> </text>
<text text-anchor="start" x="4810" y="-7426.8" font-family="Helvetica,sans-Serif" font-size="14.00">auto-incremented</text>
<text text-anchor="start" x="4574" y="-7407.8" font-family="Helvetica,sans-Serif" font-size="14.00">creation_time</text>
<text text-anchor="start" x="4731" y="-7407.8" font-family="Helvetica,sans-Serif" font-size="14.00"> </text>
<text text-anchor="start" x="4810" y="-7407.8" font-family="Helvetica,sans-Serif" font-size="14.00">timestamptz</text>
<polygon fill="none" stroke="#888888" points="4571,-7401 4571,-7479 4919,-7479 4919,-7401 4571,-7401" />
</g> <!-- signedmarkrevocationentry_99c39721&#45;&gt;signedmarkrevocationlist_c5d968fb -->
<g id="edge66" class="edge">
<title>
signedmarkrevocationentry_99c39721:w-&gt;signedmarkrevocationlist_c5d968fb:e
</title>
<path fill="none" stroke="black" d="M5232.98,-7432C5103.39,-7432 5062.36,-7432 4929.17,-7432" />
<polygon fill="black" stroke="black" points="5241,-7432 5251,-7436.5 5246,-7432 5251,-7432 5251,-7432 5251,-7432 5246,-7432 5251,-7427.5 5241,-7432 5241,-7432" />
<ellipse fill="none" stroke="black" cx="5237" cy="-7432" rx="4" ry="4" />
<polygon fill="black" stroke="black" points="4920,-7437 4920,-7427 4922,-7427 4922,-7437 4920,-7437" />
<polyline fill="none" stroke="black" points="4919,-7432 4924,-7432 " />
<polygon fill="black" stroke="black" points="4925,-7437 4925,-7427 4927,-7427 4927,-7437 4925,-7437" />
<polyline fill="none" stroke="black" points="4924,-7432 4929,-7432 " />
<text text-anchor="start" x="4981" y="-7435.8" font-family="Helvetica,sans-Serif" font-size="14.00">fk5ivlhvs3121yx2li5tqh54u4</text>
<path fill="none" stroke="black" d="M5232.98,-7450C5103.39,-7450 5062.36,-7450 4929.17,-7450" />
<polygon fill="black" stroke="black" points="5241,-7450 5251,-7454.5 5246,-7450 5251,-7450 5251,-7450 5251,-7450 5246,-7450 5251,-7445.5 5241,-7450 5241,-7450" />
<ellipse fill="none" stroke="black" cx="5237" cy="-7450" rx="4" ry="4" />
<polygon fill="black" stroke="black" points="4920,-7455 4920,-7445 4922,-7445 4922,-7455 4920,-7455" />
<polyline fill="none" stroke="black" points="4919,-7450 4924,-7450 " />
<polygon fill="black" stroke="black" points="4925,-7455 4925,-7445 4927,-7445 4927,-7455 4925,-7455" />
<polyline fill="none" stroke="black" points="4924,-7450 4929,-7450 " />
<text text-anchor="start" x="4981" y="-7453.8" font-family="Helvetica,sans-Serif" font-size="14.00">fk5ivlhvs3121yx2li5tqh54u4</text>
</g> <!-- spec11threatmatch_a61228a6 -->
<g id="node46" class="node">
<title>
spec11threatmatch_a61228a6
</title>
<polygon fill="#e9c2f2" stroke="transparent" points="5288,-7640 5288,-7659 5478,-7659 5478,-7640 5288,-7640" />
<text text-anchor="start" x="5290" y="-7646.8" font-family="Helvetica,sans-Serif" font-weight="bold" font-style="italic" font-size="14.00">public."Spec11ThreatMatch"</text>
<polygon fill="#e9c2f2" stroke="transparent" points="5478,-7640 5478,-7659 5588,-7659 5588,-7640 5478,-7640" />
<text text-anchor="start" x="5549" y="-7645.8" font-family="Helvetica,sans-Serif" font-size="14.00">[table]</text>
<text text-anchor="start" x="5290" y="-7627.8" font-family="Helvetica,sans-Serif" font-weight="bold" font-style="italic" font-size="14.00">id</text>
<text text-anchor="start" x="5432" y="-7626.8" font-family="Helvetica,sans-Serif" font-size="14.00"> </text>
<text text-anchor="start" x="5480" y="-7626.8" font-family="Helvetica,sans-Serif" font-size="14.00">bigserial not null</text>
<text text-anchor="start" x="5432" y="-7607.8" font-family="Helvetica,sans-Serif" font-size="14.00"> </text>
<text text-anchor="start" x="5480" y="-7607.8" font-family="Helvetica,sans-Serif" font-size="14.00">auto-incremented</text>
<text text-anchor="start" x="5290" y="-7588.8" font-family="Helvetica,sans-Serif" font-size="14.00">check_date</text>
<text text-anchor="start" x="5432" y="-7588.8" font-family="Helvetica,sans-Serif" font-size="14.00"> </text>
<text text-anchor="start" x="5480" y="-7588.8" font-family="Helvetica,sans-Serif" font-size="14.00">date not null</text>
<text text-anchor="start" x="5290" y="-7569.8" font-family="Helvetica,sans-Serif" font-size="14.00">domain_name</text>
<text text-anchor="start" x="5432" y="-7569.8" font-family="Helvetica,sans-Serif" font-size="14.00"> </text>
<text text-anchor="start" x="5480" y="-7569.8" font-family="Helvetica,sans-Serif" font-size="14.00">text not null</text>
<text text-anchor="start" x="5290" y="-7550.8" font-family="Helvetica,sans-Serif" font-size="14.00">domain_repo_id</text>
<text text-anchor="start" x="5432" y="-7550.8" font-family="Helvetica,sans-Serif" font-size="14.00"> </text>
<text text-anchor="start" x="5480" y="-7550.8" font-family="Helvetica,sans-Serif" font-size="14.00">text not null</text>
<text text-anchor="start" x="5290" y="-7531.8" font-family="Helvetica,sans-Serif" font-size="14.00">registrar_id</text>
<text text-anchor="start" x="5432" y="-7531.8" font-family="Helvetica,sans-Serif" font-size="14.00"> </text>
<text text-anchor="start" x="5480" y="-7531.8" font-family="Helvetica,sans-Serif" font-size="14.00">text not null</text>
<text text-anchor="start" x="5290" y="-7512.8" font-family="Helvetica,sans-Serif" font-size="14.00">threat_types</text>
<text text-anchor="start" x="5432" y="-7512.8" font-family="Helvetica,sans-Serif" font-size="14.00"> </text>
<text text-anchor="start" x="5480" y="-7512.8" font-family="Helvetica,sans-Serif" font-size="14.00">_text not null</text>
<text text-anchor="start" x="5290" y="-7493.8" font-family="Helvetica,sans-Serif" font-size="14.00">tld</text>
<text text-anchor="start" x="5432" y="-7493.8" font-family="Helvetica,sans-Serif" font-size="14.00"> </text>
<text text-anchor="start" x="5480" y="-7493.8" font-family="Helvetica,sans-Serif" font-size="14.00">text not null</text>
<polygon fill="none" stroke="#888888" points="5287,-7487.5 5287,-7660.5 5589,-7660.5 5589,-7487.5 5287,-7487.5" />
<polygon fill="#e9c2f2" stroke="transparent" points="5288,-7658 5288,-7677 5478,-7677 5478,-7658 5288,-7658" />
<text text-anchor="start" x="5290" y="-7664.8" font-family="Helvetica,sans-Serif" font-weight="bold" font-style="italic" font-size="14.00">public."Spec11ThreatMatch"</text>
<polygon fill="#e9c2f2" stroke="transparent" points="5478,-7658 5478,-7677 5588,-7677 5588,-7658 5478,-7658" />
<text text-anchor="start" x="5549" y="-7663.8" font-family="Helvetica,sans-Serif" font-size="14.00">[table]</text>
<text text-anchor="start" x="5290" y="-7645.8" font-family="Helvetica,sans-Serif" font-weight="bold" font-style="italic" font-size="14.00">id</text>
<text text-anchor="start" x="5432" y="-7644.8" font-family="Helvetica,sans-Serif" font-size="14.00"> </text>
<text text-anchor="start" x="5480" y="-7644.8" font-family="Helvetica,sans-Serif" font-size="14.00">bigserial not null</text>
<text text-anchor="start" x="5432" y="-7625.8" font-family="Helvetica,sans-Serif" font-size="14.00"> </text>
<text text-anchor="start" x="5480" y="-7625.8" font-family="Helvetica,sans-Serif" font-size="14.00">auto-incremented</text>
<text text-anchor="start" x="5290" y="-7606.8" font-family="Helvetica,sans-Serif" font-size="14.00">check_date</text>
<text text-anchor="start" x="5432" y="-7606.8" font-family="Helvetica,sans-Serif" font-size="14.00"> </text>
<text text-anchor="start" x="5480" y="-7606.8" font-family="Helvetica,sans-Serif" font-size="14.00">date not null</text>
<text text-anchor="start" x="5290" y="-7587.8" font-family="Helvetica,sans-Serif" font-size="14.00">domain_name</text>
<text text-anchor="start" x="5432" y="-7587.8" font-family="Helvetica,sans-Serif" font-size="14.00"> </text>
<text text-anchor="start" x="5480" y="-7587.8" font-family="Helvetica,sans-Serif" font-size="14.00">text not null</text>
<text text-anchor="start" x="5290" y="-7568.8" font-family="Helvetica,sans-Serif" font-size="14.00">domain_repo_id</text>
<text text-anchor="start" x="5432" y="-7568.8" font-family="Helvetica,sans-Serif" font-size="14.00"> </text>
<text text-anchor="start" x="5480" y="-7568.8" font-family="Helvetica,sans-Serif" font-size="14.00">text not null</text>
<text text-anchor="start" x="5290" y="-7549.8" font-family="Helvetica,sans-Serif" font-size="14.00">registrar_id</text>
<text text-anchor="start" x="5432" y="-7549.8" font-family="Helvetica,sans-Serif" font-size="14.00"> </text>
<text text-anchor="start" x="5480" y="-7549.8" font-family="Helvetica,sans-Serif" font-size="14.00">text not null</text>
<text text-anchor="start" x="5290" y="-7530.8" font-family="Helvetica,sans-Serif" font-size="14.00">threat_types</text>
<text text-anchor="start" x="5432" y="-7530.8" font-family="Helvetica,sans-Serif" font-size="14.00"> </text>
<text text-anchor="start" x="5480" y="-7530.8" font-family="Helvetica,sans-Serif" font-size="14.00">_text not null</text>
<text text-anchor="start" x="5290" y="-7511.8" font-family="Helvetica,sans-Serif" font-size="14.00">tld</text>
<text text-anchor="start" x="5432" y="-7511.8" font-family="Helvetica,sans-Serif" font-size="14.00"> </text>
<text text-anchor="start" x="5480" y="-7511.8" font-family="Helvetica,sans-Serif" font-size="14.00">text not null</text>
<polygon fill="none" stroke="#888888" points="5287,-7505.5 5287,-7678.5 5589,-7678.5 5589,-7505.5 5287,-7505.5" />
</g> <!-- tmchcrl_d282355 -->
<g id="node48" class="node">
<title>
tmchcrl_d282355
</title>
<polygon fill="#e9c2f2" stroke="transparent" points="5302,-7763 5302,-7782 5449,-7782 5449,-7763 5302,-7763" />
<text text-anchor="start" x="5304" y="-7769.8" font-family="Helvetica,sans-Serif" font-weight="bold" font-style="italic" font-size="14.00">public."TmchCrl"</text>
<polygon fill="#e9c2f2" stroke="transparent" points="5449,-7763 5449,-7782 5575,-7782 5575,-7763 5449,-7763" />
<text text-anchor="start" x="5536" y="-7768.8" font-family="Helvetica,sans-Serif" font-size="14.00">[table]</text>
<text text-anchor="start" x="5304" y="-7749.8" font-family="Helvetica,sans-Serif" font-size="14.00">certificate_revocations</text>
<text text-anchor="start" x="5443" y="-7749.8" font-family="Helvetica,sans-Serif" font-size="14.00"> </text>
<text text-anchor="start" x="5451" y="-7749.8" font-family="Helvetica,sans-Serif" font-size="14.00">text not null</text>
<text text-anchor="start" x="5304" y="-7730.8" font-family="Helvetica,sans-Serif" font-size="14.00">update_timestamp</text>
<text text-anchor="start" x="5443" y="-7730.8" font-family="Helvetica,sans-Serif" font-size="14.00"> </text>
<text text-anchor="start" x="5451" y="-7730.8" font-family="Helvetica,sans-Serif" font-size="14.00">timestamptz not null</text>
<text text-anchor="start" x="5304" y="-7711.8" font-family="Helvetica,sans-Serif" font-size="14.00">url</text>
<text text-anchor="start" x="5443" y="-7711.8" font-family="Helvetica,sans-Serif" font-size="14.00"> </text>
<text text-anchor="start" x="5451" y="-7711.8" font-family="Helvetica,sans-Serif" font-size="14.00">text not null</text>
<text text-anchor="start" x="5304" y="-7693.8" font-family="Helvetica,sans-Serif" font-weight="bold" font-style="italic" font-size="14.00">id</text>
<text text-anchor="start" x="5443" y="-7692.8" font-family="Helvetica,sans-Serif" font-size="14.00"> </text>
<text text-anchor="start" x="5451" y="-7692.8" font-family="Helvetica,sans-Serif" font-size="14.00">int8 not null</text>
<polygon fill="none" stroke="#888888" points="5300.5,-7686.5 5300.5,-7783.5 5575.5,-7783.5 5575.5,-7686.5 5300.5,-7686.5" />
<polygon fill="#e9c2f2" stroke="transparent" points="5302,-7781 5302,-7800 5449,-7800 5449,-7781 5302,-7781" />
<text text-anchor="start" x="5304" y="-7787.8" font-family="Helvetica,sans-Serif" font-weight="bold" font-style="italic" font-size="14.00">public."TmchCrl"</text>
<polygon fill="#e9c2f2" stroke="transparent" points="5449,-7781 5449,-7800 5575,-7800 5575,-7781 5449,-7781" />
<text text-anchor="start" x="5536" y="-7786.8" font-family="Helvetica,sans-Serif" font-size="14.00">[table]</text>
<text text-anchor="start" x="5304" y="-7767.8" font-family="Helvetica,sans-Serif" font-size="14.00">certificate_revocations</text>
<text text-anchor="start" x="5443" y="-7767.8" font-family="Helvetica,sans-Serif" font-size="14.00"> </text>
<text text-anchor="start" x="5451" y="-7767.8" font-family="Helvetica,sans-Serif" font-size="14.00">text not null</text>
<text text-anchor="start" x="5304" y="-7748.8" font-family="Helvetica,sans-Serif" font-size="14.00">update_timestamp</text>
<text text-anchor="start" x="5443" y="-7748.8" font-family="Helvetica,sans-Serif" font-size="14.00"> </text>
<text text-anchor="start" x="5451" y="-7748.8" font-family="Helvetica,sans-Serif" font-size="14.00">timestamptz not null</text>
<text text-anchor="start" x="5304" y="-7729.8" font-family="Helvetica,sans-Serif" font-size="14.00">url</text>
<text text-anchor="start" x="5443" y="-7729.8" font-family="Helvetica,sans-Serif" font-size="14.00"> </text>
<text text-anchor="start" x="5451" y="-7729.8" font-family="Helvetica,sans-Serif" font-size="14.00">text not null</text>
<text text-anchor="start" x="5304" y="-7711.8" font-family="Helvetica,sans-Serif" font-weight="bold" font-style="italic" font-size="14.00">id</text>
<text text-anchor="start" x="5443" y="-7710.8" font-family="Helvetica,sans-Serif" font-size="14.00"> </text>
<text text-anchor="start" x="5451" y="-7710.8" font-family="Helvetica,sans-Serif" font-size="14.00">int8 not null</text>
<polygon fill="none" stroke="#888888" points="5300.5,-7704.5 5300.5,-7801.5 5575.5,-7801.5 5575.5,-7704.5 5300.5,-7704.5" />
</g> <!-- userupdatehistory_24efd476 -->
<g id="node50" class="node">
<title>
userupdatehistory_24efd476
</title>
<polygon fill="#e9c2f2" stroke="transparent" points="5280,-8096 5280,-8115 5470,-8115 5470,-8096 5280,-8096" />
<text text-anchor="start" x="5282" y="-8102.8" font-family="Helvetica,sans-Serif" font-weight="bold" font-style="italic" font-size="14.00">public."UserUpdateHistory"</text>
<polygon fill="#e9c2f2" stroke="transparent" points="5470,-8096 5470,-8115 5596,-8115 5596,-8096 5470,-8096" />
<text text-anchor="start" x="5557" y="-8101.8" font-family="Helvetica,sans-Serif" font-size="14.00">[table]</text>
<text text-anchor="start" x="5282" y="-8083.8" font-family="Helvetica,sans-Serif" font-weight="bold" font-style="italic" font-size="14.00">history_revision_id</text>
<text text-anchor="start" x="5464" y="-8082.8" font-family="Helvetica,sans-Serif" font-size="14.00"> </text>
<text text-anchor="start" x="5472" y="-8082.8" font-family="Helvetica,sans-Serif" font-size="14.00">int8 not null</text>
<text text-anchor="start" x="5282" y="-8063.8" font-family="Helvetica,sans-Serif" font-size="14.00">history_modification_time</text>
<text text-anchor="start" x="5464" y="-8063.8" font-family="Helvetica,sans-Serif" font-size="14.00"> </text>
<text text-anchor="start" x="5472" y="-8063.8" font-family="Helvetica,sans-Serif" font-size="14.00">timestamptz not null</text>
<text text-anchor="start" x="5282" y="-8044.8" font-family="Helvetica,sans-Serif" font-size="14.00">history_method</text>
<text text-anchor="start" x="5464" y="-8044.8" font-family="Helvetica,sans-Serif" font-size="14.00"> </text>
<text text-anchor="start" x="5472" y="-8044.8" font-family="Helvetica,sans-Serif" font-size="14.00">text not null</text>
<text text-anchor="start" x="5282" y="-8025.8" font-family="Helvetica,sans-Serif" font-size="14.00">history_request_body</text>
<text text-anchor="start" x="5464" y="-8025.8" font-family="Helvetica,sans-Serif" font-size="14.00"> </text>
<text text-anchor="start" x="5472" y="-8025.8" font-family="Helvetica,sans-Serif" font-size="14.00">text</text>
<text text-anchor="start" x="5282" y="-8006.8" font-family="Helvetica,sans-Serif" font-size="14.00">history_type</text>
<text text-anchor="start" x="5464" y="-8006.8" font-family="Helvetica,sans-Serif" font-size="14.00"> </text>
<text text-anchor="start" x="5472" y="-8006.8" font-family="Helvetica,sans-Serif" font-size="14.00">text not null</text>
<text text-anchor="start" x="5282" y="-7987.8" font-family="Helvetica,sans-Serif" font-size="14.00">history_url</text>
<text text-anchor="start" x="5464" y="-7987.8" font-family="Helvetica,sans-Serif" font-size="14.00"> </text>
<text text-anchor="start" x="5472" y="-7987.8" font-family="Helvetica,sans-Serif" font-size="14.00">text not null</text>
<text text-anchor="start" x="5282" y="-7968.8" font-family="Helvetica,sans-Serif" font-size="14.00">email_address</text>
<text text-anchor="start" x="5464" y="-7968.8" font-family="Helvetica,sans-Serif" font-size="14.00"> </text>
<text text-anchor="start" x="5472" y="-7968.8" font-family="Helvetica,sans-Serif" font-size="14.00">text not null</text>
<text text-anchor="start" x="5282" y="-7949.8" font-family="Helvetica,sans-Serif" font-size="14.00">registry_lock_password_hash</text>
<text text-anchor="start" x="5464" y="-7949.8" font-family="Helvetica,sans-Serif" font-size="14.00"> </text>
<text text-anchor="start" x="5472" y="-7949.8" font-family="Helvetica,sans-Serif" font-size="14.00">text</text>
<text text-anchor="start" x="5282" y="-7930.8" font-family="Helvetica,sans-Serif" font-size="14.00">registry_lock_password_salt</text>
<text text-anchor="start" x="5464" y="-7930.8" font-family="Helvetica,sans-Serif" font-size="14.00"> </text>
<text text-anchor="start" x="5472" y="-7930.8" font-family="Helvetica,sans-Serif" font-size="14.00">text</text>
<text text-anchor="start" x="5282" y="-7911.8" font-family="Helvetica,sans-Serif" font-size="14.00">global_role</text>
<text text-anchor="start" x="5464" y="-7911.8" font-family="Helvetica,sans-Serif" font-size="14.00"> </text>
<text text-anchor="start" x="5472" y="-7911.8" font-family="Helvetica,sans-Serif" font-size="14.00">text not null</text>
<text text-anchor="start" x="5282" y="-7892.8" font-family="Helvetica,sans-Serif" font-size="14.00">is_admin</text>
<text text-anchor="start" x="5464" y="-7892.8" font-family="Helvetica,sans-Serif" font-size="14.00"> </text>
<text text-anchor="start" x="5472" y="-7892.8" font-family="Helvetica,sans-Serif" font-size="14.00">bool not null</text>
<text text-anchor="start" x="5282" y="-7873.8" font-family="Helvetica,sans-Serif" font-size="14.00">registrar_roles</text>
<text text-anchor="start" x="5464" y="-7873.8" font-family="Helvetica,sans-Serif" font-size="14.00"> </text>
<text text-anchor="start" x="5472" y="-7873.8" font-family="Helvetica,sans-Serif" font-size="14.00">hstore</text>
<text text-anchor="start" x="5282" y="-7854.8" font-family="Helvetica,sans-Serif" font-size="14.00">update_timestamp</text>
<text text-anchor="start" x="5464" y="-7854.8" font-family="Helvetica,sans-Serif" font-size="14.00"> </text>
<text text-anchor="start" x="5472" y="-7854.8" font-family="Helvetica,sans-Serif" font-size="14.00">timestamptz</text>
<text text-anchor="start" x="5282" y="-7835.8" font-family="Helvetica,sans-Serif" font-size="14.00">history_acting_user</text>
<text text-anchor="start" x="5464" y="-7835.8" font-family="Helvetica,sans-Serif" font-size="14.00"> </text>
<text text-anchor="start" x="5472" y="-7835.8" font-family="Helvetica,sans-Serif" font-size="14.00">text not null</text>
<text text-anchor="start" x="5282" y="-7816.8" font-family="Helvetica,sans-Serif" font-size="14.00">registry_lock_email_address</text>
<text text-anchor="start" x="5464" y="-7816.8" font-family="Helvetica,sans-Serif" font-size="14.00"> </text>
<text text-anchor="start" x="5472" y="-7816.8" font-family="Helvetica,sans-Serif" font-size="14.00">text</text>
<polygon fill="none" stroke="#888888" points="5279,-7810 5279,-8116 5597,-8116 5597,-7810 5279,-7810" />
<polygon fill="#e9c2f2" stroke="transparent" points="5280,-8114 5280,-8133 5470,-8133 5470,-8114 5280,-8114" />
<text text-anchor="start" x="5282" y="-8120.8" font-family="Helvetica,sans-Serif" font-weight="bold" font-style="italic" font-size="14.00">public."UserUpdateHistory"</text>
<polygon fill="#e9c2f2" stroke="transparent" points="5470,-8114 5470,-8133 5596,-8133 5596,-8114 5470,-8114" />
<text text-anchor="start" x="5557" y="-8119.8" font-family="Helvetica,sans-Serif" font-size="14.00">[table]</text>
<text text-anchor="start" x="5282" y="-8101.8" font-family="Helvetica,sans-Serif" font-weight="bold" font-style="italic" font-size="14.00">history_revision_id</text>
<text text-anchor="start" x="5464" y="-8100.8" font-family="Helvetica,sans-Serif" font-size="14.00"> </text>
<text text-anchor="start" x="5472" y="-8100.8" font-family="Helvetica,sans-Serif" font-size="14.00">int8 not null</text>
<text text-anchor="start" x="5282" y="-8081.8" font-family="Helvetica,sans-Serif" font-size="14.00">history_modification_time</text>
<text text-anchor="start" x="5464" y="-8081.8" font-family="Helvetica,sans-Serif" font-size="14.00"> </text>
<text text-anchor="start" x="5472" y="-8081.8" font-family="Helvetica,sans-Serif" font-size="14.00">timestamptz not null</text>
<text text-anchor="start" x="5282" y="-8062.8" font-family="Helvetica,sans-Serif" font-size="14.00">history_method</text>
<text text-anchor="start" x="5464" y="-8062.8" font-family="Helvetica,sans-Serif" font-size="14.00"> </text>
<text text-anchor="start" x="5472" y="-8062.8" font-family="Helvetica,sans-Serif" font-size="14.00">text not null</text>
<text text-anchor="start" x="5282" y="-8043.8" font-family="Helvetica,sans-Serif" font-size="14.00">history_request_body</text>
<text text-anchor="start" x="5464" y="-8043.8" font-family="Helvetica,sans-Serif" font-size="14.00"> </text>
<text text-anchor="start" x="5472" y="-8043.8" font-family="Helvetica,sans-Serif" font-size="14.00">text</text>
<text text-anchor="start" x="5282" y="-8024.8" font-family="Helvetica,sans-Serif" font-size="14.00">history_type</text>
<text text-anchor="start" x="5464" y="-8024.8" font-family="Helvetica,sans-Serif" font-size="14.00"> </text>
<text text-anchor="start" x="5472" y="-8024.8" font-family="Helvetica,sans-Serif" font-size="14.00">text not null</text>
<text text-anchor="start" x="5282" y="-8005.8" font-family="Helvetica,sans-Serif" font-size="14.00">history_url</text>
<text text-anchor="start" x="5464" y="-8005.8" font-family="Helvetica,sans-Serif" font-size="14.00"> </text>
<text text-anchor="start" x="5472" y="-8005.8" font-family="Helvetica,sans-Serif" font-size="14.00">text not null</text>
<text text-anchor="start" x="5282" y="-7986.8" font-family="Helvetica,sans-Serif" font-size="14.00">email_address</text>
<text text-anchor="start" x="5464" y="-7986.8" font-family="Helvetica,sans-Serif" font-size="14.00"> </text>
<text text-anchor="start" x="5472" y="-7986.8" font-family="Helvetica,sans-Serif" font-size="14.00">text not null</text>
<text text-anchor="start" x="5282" y="-7967.8" font-family="Helvetica,sans-Serif" font-size="14.00">registry_lock_password_hash</text>
<text text-anchor="start" x="5464" y="-7967.8" font-family="Helvetica,sans-Serif" font-size="14.00"> </text>
<text text-anchor="start" x="5472" y="-7967.8" font-family="Helvetica,sans-Serif" font-size="14.00">text</text>
<text text-anchor="start" x="5282" y="-7948.8" font-family="Helvetica,sans-Serif" font-size="14.00">registry_lock_password_salt</text>
<text text-anchor="start" x="5464" y="-7948.8" font-family="Helvetica,sans-Serif" font-size="14.00"> </text>
<text text-anchor="start" x="5472" y="-7948.8" font-family="Helvetica,sans-Serif" font-size="14.00">text</text>
<text text-anchor="start" x="5282" y="-7929.8" font-family="Helvetica,sans-Serif" font-size="14.00">global_role</text>
<text text-anchor="start" x="5464" y="-7929.8" font-family="Helvetica,sans-Serif" font-size="14.00"> </text>
<text text-anchor="start" x="5472" y="-7929.8" font-family="Helvetica,sans-Serif" font-size="14.00">text not null</text>
<text text-anchor="start" x="5282" y="-7910.8" font-family="Helvetica,sans-Serif" font-size="14.00">is_admin</text>
<text text-anchor="start" x="5464" y="-7910.8" font-family="Helvetica,sans-Serif" font-size="14.00"> </text>
<text text-anchor="start" x="5472" y="-7910.8" font-family="Helvetica,sans-Serif" font-size="14.00">bool not null</text>
<text text-anchor="start" x="5282" y="-7891.8" font-family="Helvetica,sans-Serif" font-size="14.00">registrar_roles</text>
<text text-anchor="start" x="5464" y="-7891.8" font-family="Helvetica,sans-Serif" font-size="14.00"> </text>
<text text-anchor="start" x="5472" y="-7891.8" font-family="Helvetica,sans-Serif" font-size="14.00">hstore</text>
<text text-anchor="start" x="5282" y="-7872.8" font-family="Helvetica,sans-Serif" font-size="14.00">update_timestamp</text>
<text text-anchor="start" x="5464" y="-7872.8" font-family="Helvetica,sans-Serif" font-size="14.00"> </text>
<text text-anchor="start" x="5472" y="-7872.8" font-family="Helvetica,sans-Serif" font-size="14.00">timestamptz</text>
<text text-anchor="start" x="5282" y="-7853.8" font-family="Helvetica,sans-Serif" font-size="14.00">history_acting_user</text>
<text text-anchor="start" x="5464" y="-7853.8" font-family="Helvetica,sans-Serif" font-size="14.00"> </text>
<text text-anchor="start" x="5472" y="-7853.8" font-family="Helvetica,sans-Serif" font-size="14.00">text not null</text>
<text text-anchor="start" x="5282" y="-7834.8" font-family="Helvetica,sans-Serif" font-size="14.00">registry_lock_email_address</text>
<text text-anchor="start" x="5464" y="-7834.8" font-family="Helvetica,sans-Serif" font-size="14.00"> </text>
<text text-anchor="start" x="5472" y="-7834.8" font-family="Helvetica,sans-Serif" font-size="14.00">text</text>
<polygon fill="none" stroke="#888888" points="5279,-7828 5279,-8134 5597,-8134 5597,-7828 5279,-7828" />
</g>
</g>
</svg>
@@ -9933,6 +9936,11 @@ td.section {
<td class="minwidth"><b><i>verification_code</i></b></td>
<td class="minwidth">text not null</td>
</tr>
<tr>
<td class="spacer"></td>
<td class="minwidth">registrar_id</td>
<td class="minwidth">text not null</td>
</tr>
<tr>
<td colspan="3"></td>
</tr>

View File

@@ -191,3 +191,4 @@ V190__remove_fk_registrarupdatehistory.sql
V191__remove_fk_registrarpocupdatehistory.sql
V192__add_last_poc_verification_date.sql
V193__password_reset_request.sql
V194__password_reset_request_registrar.sql

View File

@@ -0,0 +1,17 @@
-- Copyright 2025 The Nomulus Authors. All Rights Reserved.
--
-- Licensed under the Apache License, Version 2.0 (the "License");
-- you may not use this file except in compliance with the License.
-- You may obtain a copy of the License at
--
-- http://www.apache.org/licenses/LICENSE-2.0
--
-- Unless required by applicable law or agreed to in writing, software
-- distributed under the License is distributed on an "AS IS" BASIS,
-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-- See the License for the specific language governing permissions and
-- limitations under the License.
ALTER TABLE "PasswordResetRequest" ADD COLUMN registrar_id text;
UPDATE "PasswordResetRequest" SET registrar_id = '' WHERE registrar_id IS NULL;
ALTER TABLE "PasswordResetRequest" ALTER COLUMN registrar_id SET NOT NULL;

View File

@@ -852,7 +852,8 @@ CREATE TABLE public."PasswordResetRequest" (
requester text NOT NULL,
fulfillment_time timestamp with time zone,
destination_email text NOT NULL,
verification_code text NOT NULL
verification_code text NOT NULL,
registrar_id text NOT NULL
);