mirror of
https://github.com/bigcapitalhq/bigcapital.git
synced 2026-02-15 04:10:32 +00:00
feat(server): Events tracking using Posthog
This commit is contained in:
24
packages/server/src/services/EventsTracker/PostHog.ts
Normal file
24
packages/server/src/services/EventsTracker/PostHog.ts
Normal file
@@ -0,0 +1,24 @@
|
||||
import { PostHog } from 'posthog-node';
|
||||
import { Service } from 'typedi';
|
||||
import { EventMessage } from 'posthog-node/src/types';
|
||||
import config from '@/config';
|
||||
|
||||
@Service()
|
||||
export class PosthogService {
|
||||
public posthog: PostHog;
|
||||
|
||||
constructor() {
|
||||
if (config.posthog.apiKey && config.posthog.host) {
|
||||
this.posthog = new PostHog(config.posthog.apiKey, {
|
||||
host: config.posthog.host,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
public trackEvent(event: EventMessage) {
|
||||
// Cannot continue if the Posthog not configured.
|
||||
if (!this.posthog) return;
|
||||
|
||||
this.posthog.capture(event);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,65 @@
|
||||
import { Inject, Service } from 'typedi';
|
||||
import { EventSubscriber } from '@/lib/EventPublisher/EventPublisher';
|
||||
import {
|
||||
IAccountEventCreatedPayload,
|
||||
IAccountEventEditedPayload,
|
||||
IAccountEventDeletedPayload,
|
||||
} from '@/interfaces';
|
||||
import { PosthogService } from '../PostHog';
|
||||
import events from '@/subscribers/events';
|
||||
import {
|
||||
ACCOUNT_CREATED,
|
||||
ACCOUNT_EDITED,
|
||||
ACCOUNT_DELETED,
|
||||
} from '@/constants/event-tracker';
|
||||
|
||||
@Service()
|
||||
export class AccountEventsTracker extends EventSubscriber {
|
||||
@Inject()
|
||||
private posthog: PosthogService;
|
||||
|
||||
/**
|
||||
* Constructor method.
|
||||
*/
|
||||
public attach(bus) {
|
||||
bus.subscribe(
|
||||
events.accounts.onCreated,
|
||||
this.handleTrackAccountCreatedEvent
|
||||
);
|
||||
bus.subscribe(events.accounts.onEdited, this.handleTrackEditedAccountEvent);
|
||||
bus.subscribe(
|
||||
events.accounts.onDeleted,
|
||||
this.handleTrackDeletedAccountEvent
|
||||
);
|
||||
}
|
||||
|
||||
private handleTrackAccountCreatedEvent = ({
|
||||
tenantId,
|
||||
}: IAccountEventCreatedPayload) => {
|
||||
this.posthog.trackEvent({
|
||||
distinctId: `tenant-${tenantId}`,
|
||||
event: ACCOUNT_CREATED,
|
||||
properties: {},
|
||||
});
|
||||
};
|
||||
|
||||
private handleTrackEditedAccountEvent = ({
|
||||
tenantId,
|
||||
}: IAccountEventEditedPayload) => {
|
||||
this.posthog.trackEvent({
|
||||
distinctId: `tenant-${tenantId}`,
|
||||
event: ACCOUNT_EDITED,
|
||||
properties: {},
|
||||
});
|
||||
};
|
||||
|
||||
private handleTrackDeletedAccountEvent = ({
|
||||
tenantId,
|
||||
}: IAccountEventDeletedPayload) => {
|
||||
this.posthog.trackEvent({
|
||||
distinctId: `tenant-${tenantId}`,
|
||||
event: ACCOUNT_DELETED,
|
||||
properties: {},
|
||||
});
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
import { Inject, Service } from 'typedi';
|
||||
import { EventSubscriber } from '@/lib/EventPublisher/EventPublisher';
|
||||
import { IAuthSignedUpEventPayload } from '@/interfaces';
|
||||
import { PosthogService } from '../PostHog';
|
||||
import { AUTH_SIGNED_UP } from '@/constants/event-tracker';
|
||||
import events from '@/subscribers/events';
|
||||
|
||||
@Service()
|
||||
export class AuthenticationEventsTracker extends EventSubscriber {
|
||||
@Inject()
|
||||
private posthog: PosthogService;
|
||||
|
||||
/**
|
||||
* Constructor method.
|
||||
*/
|
||||
public attach(bus) {
|
||||
bus.subscribe(events.auth.signUp, this.handleTrackSignUpEvent);
|
||||
}
|
||||
|
||||
private handleTrackSignUpEvent = ({
|
||||
signupDTO,
|
||||
user,
|
||||
tenant,
|
||||
}: IAuthSignedUpEventPayload) => {
|
||||
this.posthog.trackEvent({
|
||||
distinctId: user.email,
|
||||
event: AUTH_SIGNED_UP,
|
||||
properties: {
|
||||
firstName: user.firstName,
|
||||
lastName: user.lastName,
|
||||
email: user.email,
|
||||
},
|
||||
});
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,59 @@
|
||||
import { Inject, Service } from 'typedi';
|
||||
import { EventSubscriber } from '@/lib/EventPublisher/EventPublisher';
|
||||
import {
|
||||
IBillPaymentEventCreatedPayload,
|
||||
IBillPaymentEventEditedPayload,
|
||||
IBillPaymentEventDeletedPayload,
|
||||
} from '@/interfaces';
|
||||
import { PosthogService } from '../PostHog';
|
||||
import events from '@/subscribers/events';
|
||||
import {
|
||||
BILL_CREATED,
|
||||
BILL_EDITED,
|
||||
BILL_DELETED,
|
||||
} from '@/constants/event-tracker';
|
||||
|
||||
@Service()
|
||||
export class BillEventsTracker extends EventSubscriber {
|
||||
@Inject()
|
||||
private posthog: PosthogService;
|
||||
|
||||
/**
|
||||
* Constructor method.
|
||||
*/
|
||||
public attach(bus) {
|
||||
bus.subscribe(events.bill.onCreated, this.handleTrackBillCreatedEvent);
|
||||
bus.subscribe(events.bill.onEdited, this.handleTrackEditedBillEvent);
|
||||
bus.subscribe(events.bill.onDeleted, this.handleTrackDeletedBillEvent);
|
||||
}
|
||||
|
||||
private handleTrackBillCreatedEvent = ({
|
||||
tenantId,
|
||||
}: IBillPaymentEventCreatedPayload) => {
|
||||
this.posthog.trackEvent({
|
||||
distinctId: `tenant-${tenantId}`,
|
||||
event: BILL_CREATED,
|
||||
properties: {},
|
||||
});
|
||||
};
|
||||
|
||||
private handleTrackEditedBillEvent = ({
|
||||
tenantId,
|
||||
}: IBillPaymentEventEditedPayload) => {
|
||||
this.posthog.trackEvent({
|
||||
distinctId: `tenant-${tenantId}`,
|
||||
event: BILL_EDITED,
|
||||
properties: {},
|
||||
});
|
||||
};
|
||||
|
||||
private handleTrackDeletedBillEvent = ({
|
||||
tenantId,
|
||||
}: IBillPaymentEventDeletedPayload) => {
|
||||
this.posthog.trackEvent({
|
||||
distinctId: `tenant-${tenantId}`,
|
||||
event: BILL_DELETED,
|
||||
properties: {},
|
||||
});
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,65 @@
|
||||
import { Inject, Service } from 'typedi';
|
||||
import { EventSubscriber } from '@/lib/EventPublisher/EventPublisher';
|
||||
import {
|
||||
IExpenseCreatedPayload,
|
||||
IExpenseEventEditPayload,
|
||||
IExpenseEventDeletePayload,
|
||||
} from '@/interfaces';
|
||||
import { PosthogService } from '../PostHog';
|
||||
import events from '@/subscribers/events';
|
||||
import {
|
||||
EXPENSE_CREATED,
|
||||
EXPENSE_EDITED,
|
||||
EXPENSE_DELETED,
|
||||
} from '@/constants/event-tracker';
|
||||
|
||||
@Service()
|
||||
export class ExpenseEventsTracker extends EventSubscriber {
|
||||
@Inject()
|
||||
private posthog: PosthogService;
|
||||
|
||||
/**
|
||||
* Constructor method.
|
||||
*/
|
||||
public attach(bus) {
|
||||
bus.subscribe(
|
||||
events.expenses.onCreated,
|
||||
this.handleTrackExpenseCreatedEvent
|
||||
);
|
||||
bus.subscribe(events.expenses.onEdited, this.handleTrackEditedExpenseEvent);
|
||||
bus.subscribe(
|
||||
events.expenses.onDeleted,
|
||||
this.handleTrackDeletedExpenseEvent
|
||||
);
|
||||
}
|
||||
|
||||
private handleTrackExpenseCreatedEvent = ({
|
||||
tenantId,
|
||||
}: IExpenseCreatedPayload) => {
|
||||
this.posthog.trackEvent({
|
||||
distinctId: `tenant-${tenantId}`,
|
||||
event: EXPENSE_CREATED,
|
||||
properties: {},
|
||||
});
|
||||
};
|
||||
|
||||
private handleTrackEditedExpenseEvent = ({
|
||||
tenantId,
|
||||
}: IExpenseEventEditPayload) => {
|
||||
this.posthog.trackEvent({
|
||||
distinctId: `tenant-${tenantId}`,
|
||||
event: EXPENSE_EDITED,
|
||||
properties: {},
|
||||
});
|
||||
};
|
||||
|
||||
private handleTrackDeletedExpenseEvent = ({
|
||||
tenantId,
|
||||
}: IExpenseEventDeletePayload) => {
|
||||
this.posthog.trackEvent({
|
||||
distinctId: `tenant-${tenantId}`,
|
||||
event: EXPENSE_DELETED,
|
||||
properties: {},
|
||||
});
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,59 @@
|
||||
import { Inject, Service } from 'typedi';
|
||||
import { EventSubscriber } from '@/lib/EventPublisher/EventPublisher';
|
||||
import {
|
||||
IItemEventCreatedPayload,
|
||||
IItemEventEditedPayload,
|
||||
IItemEventDeletedPayload,
|
||||
} from '@/interfaces';
|
||||
import { PosthogService } from '../PostHog';
|
||||
import events from '@/subscribers/events';
|
||||
import {
|
||||
ITEM_EVENT_CREATED,
|
||||
ITEM_EVENT_EDITED,
|
||||
ITEM_EVENT_DELETED,
|
||||
} from '@/constants/event-tracker';
|
||||
|
||||
@Service()
|
||||
export class ItemEventsTracker extends EventSubscriber {
|
||||
@Inject()
|
||||
private posthog: PosthogService;
|
||||
|
||||
/**
|
||||
* Constructor method.
|
||||
*/
|
||||
public attach(bus) {
|
||||
bus.subscribe(events.item.onCreated, this.handleTrackItemCreatedEvent);
|
||||
bus.subscribe(events.item.onEdited, this.handleTrackEditedItemEvent);
|
||||
bus.subscribe(events.item.onDeleted, this.handleTrackDeletedItemEvent);
|
||||
}
|
||||
|
||||
private handleTrackItemCreatedEvent = ({
|
||||
tenantId,
|
||||
}: IItemEventCreatedPayload) => {
|
||||
this.posthog.trackEvent({
|
||||
distinctId: `tenant-${tenantId}`,
|
||||
event: ITEM_EVENT_CREATED,
|
||||
properties: {},
|
||||
});
|
||||
};
|
||||
|
||||
private handleTrackEditedItemEvent = ({
|
||||
tenantId,
|
||||
}: IItemEventEditedPayload) => {
|
||||
this.posthog.trackEvent({
|
||||
distinctId: `tenant-${tenantId}`,
|
||||
event: ITEM_EVENT_EDITED,
|
||||
properties: {},
|
||||
});
|
||||
};
|
||||
|
||||
private handleTrackDeletedItemEvent = ({
|
||||
tenantId,
|
||||
}: IItemEventDeletedPayload) => {
|
||||
this.posthog.trackEvent({
|
||||
distinctId: `tenant-${tenantId}`,
|
||||
event: ITEM_EVENT_DELETED,
|
||||
properties: {},
|
||||
});
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,68 @@
|
||||
import { Inject, Service } from 'typedi';
|
||||
import { EventSubscriber } from '@/lib/EventPublisher/EventPublisher';
|
||||
import {
|
||||
IBillPaymentEventCreatedPayload,
|
||||
IBillPaymentEditingPayload,
|
||||
IBillPaymentEventDeletedPayload,
|
||||
} from '@/interfaces';
|
||||
import { PosthogService } from '../PostHog';
|
||||
import events from '@/subscribers/events';
|
||||
import {
|
||||
PAYMENT_MADE_CREATED,
|
||||
PAYMENT_MADE_EDITED,
|
||||
PAYMENT_MADE_DELETED,
|
||||
} from '@/constants/event-tracker';
|
||||
|
||||
@Service()
|
||||
export class PaymentMadeEventsTracker extends EventSubscriber {
|
||||
@Inject()
|
||||
private posthog: PosthogService;
|
||||
|
||||
/**
|
||||
* Constructor method.
|
||||
*/
|
||||
public attach(bus) {
|
||||
bus.subscribe(
|
||||
events.billPayment.onCreated,
|
||||
this.handleTrackPaymentMadeCreatedEvent
|
||||
);
|
||||
bus.subscribe(
|
||||
events.billPayment.onEdited,
|
||||
this.handleTrackEditedPaymentMadeEvent
|
||||
);
|
||||
bus.subscribe(
|
||||
events.billPayment.onDeleted,
|
||||
this.handleTrackDeletedPaymentMadeEvent
|
||||
);
|
||||
}
|
||||
|
||||
private handleTrackPaymentMadeCreatedEvent = ({
|
||||
tenantId,
|
||||
}: IBillPaymentEventCreatedPayload) => {
|
||||
this.posthog.trackEvent({
|
||||
distinctId: `tenant-${tenantId}`,
|
||||
event: PAYMENT_MADE_CREATED,
|
||||
properties: {},
|
||||
});
|
||||
};
|
||||
|
||||
private handleTrackEditedPaymentMadeEvent = ({
|
||||
tenantId,
|
||||
}: IBillPaymentEditingPayload) => {
|
||||
this.posthog.trackEvent({
|
||||
distinctId: `tenant-${tenantId}`,
|
||||
event: PAYMENT_MADE_EDITED,
|
||||
properties: {},
|
||||
});
|
||||
};
|
||||
|
||||
private handleTrackDeletedPaymentMadeEvent = ({
|
||||
tenantId,
|
||||
}: IBillPaymentEventDeletedPayload) => {
|
||||
this.posthog.trackEvent({
|
||||
distinctId: `tenant-${tenantId}`,
|
||||
event: PAYMENT_MADE_DELETED,
|
||||
properties: {},
|
||||
});
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,68 @@
|
||||
import { Inject, Service } from 'typedi';
|
||||
import { EventSubscriber } from '@/lib/EventPublisher/EventPublisher';
|
||||
import {
|
||||
IPaymentReceivedCreatedPayload,
|
||||
IPaymentReceivedEditedPayload,
|
||||
IPaymentReceivedDeletedPayload,
|
||||
} from '@/interfaces';
|
||||
import { PosthogService } from '../PostHog';
|
||||
import events from '@/subscribers/events';
|
||||
import {
|
||||
PAYMENT_RECEIVED_CREATED,
|
||||
PAYMENT_RECEIVED_EDITED,
|
||||
PAYMENT_RECEIVED_DELETED,
|
||||
} from '@/constants/event-tracker';
|
||||
|
||||
@Service()
|
||||
export class PaymentReceivedEventsTracker extends EventSubscriber {
|
||||
@Inject()
|
||||
private posthog: PosthogService;
|
||||
|
||||
/**
|
||||
* Constructor method.
|
||||
*/
|
||||
public attach(bus) {
|
||||
bus.subscribe(
|
||||
events.paymentReceive.onCreated,
|
||||
this.handleTrackPaymentReceivedCreatedEvent
|
||||
);
|
||||
bus.subscribe(
|
||||
events.paymentReceive.onEdited,
|
||||
this.handleTrackEditedPaymentReceivedEvent
|
||||
);
|
||||
bus.subscribe(
|
||||
events.paymentReceive.onDeleted,
|
||||
this.handleTrackDeletedPaymentReceivedEvent
|
||||
);
|
||||
}
|
||||
|
||||
private handleTrackPaymentReceivedCreatedEvent = ({
|
||||
tenantId,
|
||||
}: IPaymentReceivedCreatedPayload) => {
|
||||
this.posthog.trackEvent({
|
||||
distinctId: `tenant-${tenantId}`,
|
||||
event: PAYMENT_RECEIVED_CREATED,
|
||||
properties: {},
|
||||
});
|
||||
};
|
||||
|
||||
private handleTrackEditedPaymentReceivedEvent = ({
|
||||
tenantId,
|
||||
}: IPaymentReceivedEditedPayload) => {
|
||||
this.posthog.trackEvent({
|
||||
distinctId: `tenant-${tenantId}`,
|
||||
event: PAYMENT_RECEIVED_EDITED,
|
||||
properties: {},
|
||||
});
|
||||
};
|
||||
|
||||
private handleTrackDeletedPaymentReceivedEvent = ({
|
||||
tenantId,
|
||||
}: IPaymentReceivedDeletedPayload) => {
|
||||
this.posthog.trackEvent({
|
||||
distinctId: `tenant-${tenantId}`,
|
||||
event: PAYMENT_RECEIVED_DELETED,
|
||||
properties: {},
|
||||
});
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,68 @@
|
||||
import { Inject, Service } from 'typedi';
|
||||
import { EventSubscriber } from '@/lib/EventPublisher/EventPublisher';
|
||||
import {
|
||||
ISaleEstimateCreatedPayload,
|
||||
ISaleEstimateEditedPayload,
|
||||
ISaleEstimateDeletedPayload,
|
||||
} from '@/interfaces';
|
||||
import { PosthogService } from '../PostHog';
|
||||
import events from '@/subscribers/events';
|
||||
import {
|
||||
SALE_ESTIMATE_CREATED,
|
||||
SALE_ESTIMATE_EDITED,
|
||||
SALE_ESTIMATE_DELETED,
|
||||
} from '@/constants/event-tracker';
|
||||
|
||||
@Service()
|
||||
export class SaleEstimateEventsTracker extends EventSubscriber {
|
||||
@Inject()
|
||||
private posthog: PosthogService;
|
||||
|
||||
/**
|
||||
* Constructor method.
|
||||
*/
|
||||
public attach(bus) {
|
||||
bus.subscribe(
|
||||
events.saleEstimate.onCreated,
|
||||
this.handleTrackEstimateCreatedEvent
|
||||
);
|
||||
bus.subscribe(
|
||||
events.saleEstimate.onEdited,
|
||||
this.handleTrackEditedEstimateEvent
|
||||
);
|
||||
bus.subscribe(
|
||||
events.saleEstimate.onDeleted,
|
||||
this.handleTrackDeletedEstimateEvent
|
||||
);
|
||||
}
|
||||
|
||||
private handleTrackEstimateCreatedEvent = ({
|
||||
tenantId,
|
||||
}: ISaleEstimateCreatedPayload) => {
|
||||
this.posthog.trackEvent({
|
||||
distinctId: `tenant-${tenantId}`,
|
||||
event: SALE_ESTIMATE_CREATED,
|
||||
properties: {},
|
||||
});
|
||||
};
|
||||
|
||||
private handleTrackEditedEstimateEvent = ({
|
||||
tenantId,
|
||||
}: ISaleEstimateEditedPayload) => {
|
||||
this.posthog.trackEvent({
|
||||
distinctId: `tenant-${tenantId}`,
|
||||
event: SALE_ESTIMATE_EDITED,
|
||||
properties: {},
|
||||
});
|
||||
};
|
||||
|
||||
private handleTrackDeletedEstimateEvent = ({
|
||||
tenantId,
|
||||
}: ISaleEstimateDeletedPayload) => {
|
||||
this.posthog.trackEvent({
|
||||
distinctId: `tenant-${tenantId}`,
|
||||
event: SALE_ESTIMATE_DELETED,
|
||||
properties: {},
|
||||
});
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,67 @@
|
||||
import { Inject, Service } from 'typedi';
|
||||
import { EventSubscriber } from '@/lib/EventPublisher/EventPublisher';
|
||||
import {
|
||||
ISaleInvoiceCreatedPayload,
|
||||
ISaleInvoiceEditedPayload,
|
||||
} from '@/interfaces';
|
||||
import { PosthogService } from '../PostHog';
|
||||
import events from '@/subscribers/events';
|
||||
import {
|
||||
SALE_INVOICE_CREATED,
|
||||
SALE_INVOICE_DELETED,
|
||||
SALE_INVOICE_EDITED,
|
||||
} from '@/constants/event-tracker';
|
||||
|
||||
@Service()
|
||||
export class SaleInvoiceEventsTracker extends EventSubscriber {
|
||||
@Inject()
|
||||
private posthog: PosthogService;
|
||||
|
||||
/**
|
||||
* Constructor method.
|
||||
*/
|
||||
public attach(bus) {
|
||||
bus.subscribe(
|
||||
events.saleInvoice.onCreated,
|
||||
this.handleTrackInvoiceCreatedEvent
|
||||
);
|
||||
bus.subscribe(
|
||||
events.saleInvoice.onEdited,
|
||||
this.handleTrackEditedInvoiceEvent
|
||||
);
|
||||
bus.subscribe(
|
||||
events.saleInvoice.onDeleted,
|
||||
this.handleTrackDeletedInvoiceEvent
|
||||
);
|
||||
}
|
||||
|
||||
private handleTrackInvoiceCreatedEvent = ({
|
||||
tenantId,
|
||||
}: ISaleInvoiceCreatedPayload) => {
|
||||
this.posthog.trackEvent({
|
||||
distinctId: `tenant-${tenantId}`,
|
||||
event: SALE_INVOICE_CREATED,
|
||||
properties: {},
|
||||
});
|
||||
};
|
||||
|
||||
private handleTrackEditedInvoiceEvent = ({
|
||||
tenantId,
|
||||
}: ISaleInvoiceEditedPayload) => {
|
||||
this.posthog.trackEvent({
|
||||
distinctId: `tenant-${tenantId}`,
|
||||
event: SALE_INVOICE_EDITED,
|
||||
properties: {},
|
||||
});
|
||||
};
|
||||
|
||||
private handleTrackDeletedInvoiceEvent = ({
|
||||
tenantId,
|
||||
}: ISaleInvoiceEditedPayload) => {
|
||||
this.posthog.trackEvent({
|
||||
distinctId: `tenant-${tenantId}`,
|
||||
event: SALE_INVOICE_DELETED,
|
||||
properties: {},
|
||||
});
|
||||
};
|
||||
}
|
||||
21
packages/server/src/services/EventsTracker/events/events.ts
Normal file
21
packages/server/src/services/EventsTracker/events/events.ts
Normal file
@@ -0,0 +1,21 @@
|
||||
import { SaleInvoiceEventsTracker } from './SaleInvoicesEventsTracker';
|
||||
import { SaleEstimateEventsTracker } from './SaleEstimateEventsTracker';
|
||||
import { PaymentMadeEventsTracker } from './PaymentMadeEventsTracker';
|
||||
import { PaymentReceivedEventsTracker } from './PaymentReceivedEventsTracker';
|
||||
import { BillEventsTracker } from './BillEventsTracker';
|
||||
import { ExpenseEventsTracker } from './ExpenseEventsTracker';
|
||||
import { AccountEventsTracker } from './AccountEventsTracker';
|
||||
import { AuthenticationEventsTracker } from './AuthenticationEventsTracker';
|
||||
import { ItemEventsTracker } from './ItemEventsTracker';
|
||||
|
||||
export const EventsTrackerListeners = [
|
||||
SaleInvoiceEventsTracker,
|
||||
SaleEstimateEventsTracker,
|
||||
PaymentMadeEventsTracker,
|
||||
PaymentReceivedEventsTracker,
|
||||
BillEventsTracker,
|
||||
AccountEventsTracker,
|
||||
ExpenseEventsTracker,
|
||||
AuthenticationEventsTracker,
|
||||
ItemEventsTracker
|
||||
];
|
||||
Reference in New Issue
Block a user