Activate Institute Portal
Learn how to activate an institute's fee portal and make it live for students and parents.
ls -la /etc/nginx/sites-available/{domain}.conf
Check symlink exists
ls -la /etc/nginx/sites-enabled/{domain}.conf
Verify Nginx configuration is valid
sudo nginx -t
Check Nginx is running
sudo systemctl status nginx
All commands should succeed without errors.
**Step 12: Test Portal Access**
**Method 1: Browser Test**
- Open a web browser
- Navigate to `http://{domain}` (e.g., `http://stmary.solidx.edu`)
- The student portal should load
- You should see the institute's fee payment interface
**Method 2: Curl Test**
```bash
curl -I http://{domain}- Should return
HTTP/1.1 200 OKorHTTP/1.1 302 Found - Should not return
404 Not Foundor connection errors
Expected Result:
- Portal loads successfully
- No certificate warnings (if HTTPS is configured)
- Institute branding appears correct
- No error messages visible
Step 13: Notify Institute Admin
Once activation is verified:
- Contact the Institute Admin via email or phone
- Provide the live portal URL
- Share any login credentials or setup instructions
- Confirm they can access the admin panel
Phase 4: Troubleshooting Failed Activation
If activation fails or portal is not accessible:
Issue: "Failed to activate institute" Error
Possible Causes:
- Missing
PORTAL_CNAME_DOMAINenvironment variable - DNS provider configuration error
- Nginx reload failure
- Insufficient server permissions
Solutions:
-
Check environment variables on server:
echo $PORTAL_CNAME_DOMAIN- Should return a valid domain
- If empty, set in
.envfile or server configuration
-
Check DNS provider configuration:
# For Route53 aws route53 list-hosted-zones # Verify hosted zone exists # For hosts file ls -la /etc/hosts # Verify file is writable -
Check Nginx status:
sudo nginx -t sudo systemctl status nginx sudo journalctl -u nginx -n 50- Look for syntax errors or reload failures
-
Check application logs:
# API logs pm2 logs solid-api # Or check log files tail -f /path/to/api/logs/error.log
Issue: Portal Returns 404 Not Found
Possible Causes:
- Nginx configuration not created
- Nginx not reloaded after configuration
- Virtual host not enabled (symlink missing)
Solutions:
-
Verify configuration file exists:
cat /etc/nginx/sites-available/{domain}.conf -
Verify symlink exists:
ls -la /etc/nginx/sites-enabled/ | grep {domain} -
Manually reload Nginx:
sudo systemctl reload nginx
Issue: DNS Not Resolving
Possible Causes:
- DNS record not created
- DNS propagation delay (Route53)
- Wrong hosted zone (Route53)
- Hosts file not updated (local)
Solutions:
-
For Route53, check record exists:
aws route53 list-resource-record-sets --hosted-zone-id {zone-id} -
For hosts file, check entry:
cat /etc/hosts | grep {domain} -
Wait 10-15 minutes for DNS propagation (production)
-
Flush DNS cache on client:
# macOS sudo dscacheutil -flushcache # Windows ipconfig /flushdns # Linux sudo systemd-resolve --flush-caches
Issue: Portal Loads But Shows Wrong Institute
Possible Causes:
- Nginx upstream configuration pointing to wrong instance
- Frontend routing not matching domain to institute
Solutions:
-
Verify Nginx proxy configuration:
cat /etc/nginx/sites-available/{domain}.conf- Check
proxy_passdirective - Should point to
EDU_FRONTEND_UPSTREAM
- Check
-
Check frontend routing logic in application code
-
Verify
hostedPagePrefixuniqueness in database
Deactivating an Institute
If you need to take a portal offline:
Deactivation Process
Step 1: Navigate to Active Institute
- Open the institute record
- Verify status is currently "Active"
- "Deactivate Institute" button should be visible
Step 2: Initiate Deactivation
- Click "Deactivate Institute" button (⊗ icon)
- Confirmation dialog appears:
- Header: "Deactivate institute?"
- Message: "Clicking Ok below will Deactivate this institute, are you sure you want to continue?"
Step 3: Confirm Deactivation
- Click "Ok" to proceed
- System will:
- Remove Nginx virtual host configuration
- Remove DNS CNAME record
- Set status to "InActive"
- Create audit trail entry
Step 4: Verify Deactivation
- Success message: "institute Deactivated successfully."
- Status changes to "InActive"
- "Activate Institute" button reappears
- Portal becomes inaccessible (404 or connection error)
When to Deactivate
Valid Reasons:
- Institute contract ended
- Switching to different platform
- Temporary suspension due to payment issues
- Maintenance or configuration changes needed
- Institute closure
Important: Deactivation only removes infrastructure - it does not delete data. Student records, payment history, and configuration remain in the database and can be reactivated later.
Technical Implementation Details
This section explains how the activation system works under the hood.
Backend Service Implementation
File: solid-api/src/fees-portal/services/institute.service.ts
Activation Method: activateInstitutePortal(id: number)
async activateInstitutePortal(id: number) {
// 1. Retrieve institute record
const institute = await this.findOne(id, {});
// 2. Construct domain name
const baseDoamin = process.env.EDU_BASE_DOMAIN || 'solidx.edu';
const domainName = `${institute.hostedPagePrefix}-${baseDoamin}`;
// 3. Create Nginx virtual host
await this.nginxVirtualHostProvider.makeVirtualHost(domainName);
// 4. Create DNS CNAME record
const portalCnameDomain = process.env.PORTAL_CNAME_DOMAIN;
if (!portalCnameDomain) {
throw new NotAcceptableException('PORTAL_CNAME_DOMAIN env var not configured');
}
await this.dns.createCnameRecord(domainName, portalCnameDomain, 300);
// 5. Update status
institute.status = 'Active';
await this.repo.save(institute);
// 6. Create audit entry
const postMessageOnActivate: PostChatterMessageDto = {
coModelEntityId: institute.id,
coModelName: 'institute',
messageBody: `
### Institute Activated
Institute is now live on domain: <a href="${domainName}" target="_blank" rel="noopener noreferrer">${domainName}</a>
`
};
await this.chatterMessageService.postMessage(postMessageOnActivate);
return { message: 'Institute activated successfully' };
}Key Points:
- Domain name constructed from
hostedPagePrefixandEDU_BASE_DOMAIN - Infrastructure provisioning happens before database update
- If any step fails, exception is thrown (status remains "InActive")
- Audit trail created after successful activation
Deactivation Method: deActivateInstitutePortal(id: number)
async deActivateInstitutePortal(id: number) {
const institute = await this.findOne(id, {});
const baseDoamin = process.env.EDU_BASE_DOMAIN || 'solidx.edu';
const domainName = `${institute.hostedPagePrefix}-${baseDoamin}`;
// 1. Remove Nginx virtual host
await this.nginxVirtualHostProvider.removeVirtualHost(domainName);
// 2. Remove DNS record
const portalCnameDomain = process.env.PORTAL_CNAME_DOMAIN;
if (!portalCnameDomain) {
throw new NotAcceptableException('PORTAL_CNAME_DOMAIN env var not configured');
}
await this.dns.removeCnameRecord(domainName, portalCnameDomain);
// 3. Update status
institute.status = 'InActive';
await this.repo.save(institute);
// 4. Create audit entry
const postMessageOnDeActivate: PostChatterMessageDto = {
coModelEntityId: institute.id,
coModelName: 'institute',
messageBody: '### Institute De Activated'
};
await this.chatterMessageService.postMessage(postMessageOnDeActivate);
return { message: 'Institute de activated successfully' };
}API Endpoints
File: solid-api/src/fees-portal/controllers/institute.controller.ts
Activation Endpoint:
@ApiBearerAuth("jwt")
@Post('activate/:id')
async activateFeePortal(@Param('id') id: number) {
return this.service.activateInstitutePortal(id);
}URL: POST /api/institute/activate/{id}
Authentication: Requires JWT Bearer token
Parameters:
id(path parameter): Institute ID to activate
Response (Success):
{
"message": "Institute activated successfully"
}Response (Error):
{
"statusCode": 406,
"message": "PORTAL_CNAME_DOMAIN env var not configured",
"error": "Not Acceptable"
}Deactivation Endpoint:
@ApiBearerAuth("jwt")
@Post('deactivate/:id')
async deactivateFeePortal(@Param('id') id: number) {
return this.service.deActivateInstitutePortal(id);
}URL: POST /api/institute/deactivate/{id}
Authentication: Requires JWT Bearer token
Parameters:
id(path parameter): Institute ID to deactivate
Response: Same structure as activation endpoint
Nginx Virtual Host Provider
File: solid-api/src/fees-portal/services/ubuntu-nginx-virtual-host-provider.ts
Purpose: Manages Nginx server block configurations for institute domains
Method: makeVirtualHost(domainName: string)
What It Does:
- Validates domain name syntax (conservative regex for ASCII hostnames)
- Renders Nginx server block template with:
- Server name:
{domainName} - Listen: Port 80
- Proxy pass:
{EDU_FRONTEND_UPSTREAM} - Proxy headers: Host, X-Real-IP, X-Forwarded-For, X-Forwarded-Proto
- Server name:
- Writes configuration to
/etc/nginx/sites-available/{domainName}.conf - Creates symlink in
/etc/nginx/sites-enabled/{domainName}.conf - Tests Nginx configuration:
nginx -t - Reloads Nginx:
systemctl reload nginx
Server Block Template:
server {
listen 80;
server_name {domainName};
location / {
proxy_pass {EDU_FRONTEND_UPSTREAM};
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}Method: removeVirtualHost(domainName: string)
What It Does:
- Removes symlink from
/etc/nginx/sites-enabled/{domainName}.conf - Removes configuration from
/etc/nginx/sites-available/{domainName}.conf - Tests Nginx configuration:
nginx -t - Reloads Nginx:
systemctl reload nginx
Error Handling:
- Throws exception if domain name is invalid
- Throws exception if Nginx test fails
- Throws exception if Nginx reload fails
- All operations are atomic (rollback on failure)
DNS Management - Route53 Provider
File: solid-api/src/fees-portal/services/route53-website-dns.manager.ts
Purpose: Manages DNS CNAME records using AWS Route53
Method: createCnameRecord(name: string, value: string, ttl: number)
What It Does:
- Constructs Route53 API request:
- Action: UPSERT (create or update)
- Type: CNAME
- Name:
{name}(e.g.,stmary.solidx.edu) - Value:
{value}(PORTAL_CNAME_DOMAIN) - TTL:
{ttl}seconds (default: 300)
- Calls Route53 API:
changeResourceRecordSets - Waits for change to propagate (async)
Prerequisites:
- AWS credentials configured (IAM role or environment variables)
- Route53 hosted zone ID provided to constructor
- Hosted zone must match
EDU_BASE_DOMAIN
Method: removeCnameRecord(name: string, value: string)
What It Does:
- Constructs Route53 API request with DELETE action
- Calls Route53 API to remove the CNAME record
- Waits for change to propagate
DNS Management - Hosts File Provider
File: solid-api/src/fees-portal/services/hosts-file-website-dns.manager.ts
Purpose: Manages DNS entries in local /etc/hosts file for development
Method: createCnameRecord(name: string, value: string, ttl: number)
What It Does:
- Reads
/etc/hostsfile - Checks if entry already exists
- If not, appends entry:
127.0.0.1 {name} # solidx-dns - Writes updated content back to
/etc/hosts
Method: removeCnameRecord(name: string, value: string)
What It Does:
- Reads
/etc/hostsfile - Filters out lines containing
{name} # solidx-dns - Writes filtered content back to
/etc/hosts
Prerequisites:
- Application runs with sudo/root privileges
/etc/hostsfile is writable- File system allows file modification
Marker System:
- All entries tagged with
# solidx-dnscomment - Allows safe removal without affecting other entries
- Prevents duplicate entries
DNS Provider Selection
File: solid-api/src/fees-portal/fees-portal.module.ts
const which = (cfg.get<string>('DNS_PROVIDER') ?? 'hosts').toLowerCase();
if (which === 'route53') {
return new Route53WebsiteDnsManager(hostedZoneId);
}
return new HostsFileWebsiteDnsManager();Logic:
- Checks
DNS_PROVIDERenvironment variable - If
"route53": Uses Route53WebsiteDnsManager - If
"hosts"or not set: Uses HostsFileWebsiteDnsManager - Case-insensitive comparison
Recommended Setup:
- Production:
DNS_PROVIDER=route53 - Local Development:
DNS_PROVIDER=hosts(or omit)
UI Components
Activate Button Component:
File: solid-ui/app/admin/extensions/headerButtons/activate-portal.tsx
Component: InstituteActivateById
export default function InstituteActivateById({ formData, refetch, onClose }: Props) {
const session = useSession();
const [loading, setLoading] = useState(false);
const handleActivate = async () => {
setLoading(true);
try {
// Call activation API
const response = await fetch(`/api/institute/activate/${formData.id}`, {
method: 'POST',
headers: {
'Authorization': `Bearer ${session.data.user.accessToken}`,
'Content-Type': 'application/json',
},
});
if (!response.ok) throw new Error('Activation failed');
// Update status in UI
await fetch(`/api/institute/${formData.id}`, {
method: 'PATCH',
headers: {
'Authorization': `Bearer ${session.data.user.accessToken}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({ status: 'Active' }),
});
toast.success('Institute activated successfully.');
onClose();
refetch();
} catch (error) {
toast.error('Failed to activate institute.');
} finally {
setLoading(false);
}
};
return (
);
}Key Features:
- Confirmation dialog prevents accidental activation
- Shows loading state during provisioning
- Success/error toast notifications
- Automatic form refresh after activation
- JWT authentication with session token
Deactivate Button Component:
File: solid-ui/app/admin/extensions/headerButtons/deActivate-portal.tsx
Component: InstituteDeactivateById
Similar structure to activate button, but:
- Different confirmation message
- Calls
/api/institute/deactivate/{id}endpoint - Sets status to "InActive" on success
Conditional UI - Edit Handler
File: solid-ui/app/admin/extensions/instituteEditHandler.ts
const instituteEditHandler = async (event: any) => {
const { viewMetadata, formData, fieldsMetadata } = event;
const { status } = formData || {};
const layoutManager = new SolidViewLayoutManager(viewMetadata.layout);
if(status === "InActive"){
layoutManager.updateNodeAttributes("InstituteActivateById", { visible: true });
layoutManager.updateNodeAttributes("InstituteDeactivateById", { visible: false });
} else if(status === "Active"){
layoutManager.updateNodeAttributes("InstituteActivateById", { visible: false });
layoutManager.updateNodeAttributes("InstituteDeactivateById", { visible: true });
}
return {
layoutChanged: true,
dataChanged: false,
newLayout: layoutManager.getLayout()
};
};
export default instituteEditHandler;Purpose: Controls button visibility based on current status
Logic:
- When status = "InActive": Show "Activate" button, hide "Deactivate" button
- When status = "Active": Show "Deactivate" button, hide "Activate" button
How It Works:
- Called when institute form loads
- Receives current form data (including status)
- Uses
SolidViewLayoutManagerto update layout - Returns modified layout to UI framework
Benefits:
- Prevents invalid actions (can't activate what's already active)
- Clear visual indication of current state
- Follows state machine pattern
UI Configuration
Button Configuration in Form View:
Both buttons are configured as header buttons in the institute form view layout:
Activate Institute Button:
{
"attrs": {
"label": "Activate Institute",
"icon": "pi pi-caret-right",
"action": "InstituteActivateById",
"customComponentIsSystem": true,
"actionInContextMenu": true,
"openInPopup": true,
"visible": false
}
}Deactivate Institute Button:
{
"attrs": {
"label": "Deactivate Institute",
"icon": "pi pi-circle-off",
"action": "InstituteDeactivateById",
"customComponentIsSystem": true,
"actionInContextMenu": true,
"openInPopup": true,
"visible": false
}
}Configuration Properties:
action: References the React component namecustomComponentIsSystem: Indicates this is a custom component (not auto-generated)actionInContextMenu: Shows button in context menu (right-click/three-dot menu)openInPopup: Opens in a modal dialogvisible: Initially hidden (controlled by edit handler)
Security Considerations
Authentication & Authorization
Endpoint Security:
- All activation/deactivation endpoints require JWT authentication
- Bearer token must be included in request headers
- Token validated by NestJS authentication guards
Role-Based Access Control:
- Only Platform Admin role can activate/deactivate institutes
- Institute Admins cannot activate their own institute
- Role check enforced at framework level
Recommended Enhancement: Add explicit role guard to controller:
@ApiBearerAuth("jwt")
@UseGuards(JwtAuthGuard, RolesGuard)
@Roles('Platform Admin')
@Post('activate/:id')
async activateFeePortal(@Param('id') id: number) {
return this.service.activateInstitutePortal(id);
}Infrastructure Security
Nginx Configuration:
- Virtual hosts isolated per institute
- No cross-domain access
- Proxy headers sanitized
- HTTP only (upgrade to HTTPS recommended)
DNS Security:
- CNAME records validated before creation
- Domain name sanitized (conservative regex)
- TTL set to reasonable value (300s)
File System Security:
- Configuration files created with restricted permissions
- Only application service account can modify
- Nginx runs as separate user (www-data)
Audit & Compliance
Audit Trail:
- All activation/deactivation events logged to Chatter
- Timestamp, user, and action recorded
- Immutable audit log
Rollback Capability:
- Deactivation removes infrastructure but preserves data
- Can reactivate institute without data loss
- Configuration history maintained
Environment Configuration Reference
This section details all environment variables used by the activation system.
Required Environment Variables
PORTAL_CNAME_DOMAIN
- Description: Target domain for CNAME records
- Required: Yes
- Example:
"portal.solidx.edu" - Used By: DNS record creation
- Impact if Missing: Activation fails with error
Optional Environment Variables
EDU_BASE_DOMAIN
- Description: Base domain for institute subdomains
- Required: No
- Default:
"solidx.edu" - Example:
"edu.yourcompany.com" - Used By: Domain name construction
DNS_PROVIDER
- Description: DNS management provider
- Required: No
- Default:
"hosts" - Allowed Values:
"route53","hosts" - Example:
"route53" - Used By: DNS provider selection
EDU_FRONTEND_UPSTREAM
- Description: Upstream server for Nginx proxy
- Required: No
- Default:
"http://127.0.0.1:3002" - Example:
"http://localhost:3000" - Used By: Nginx virtual host configuration
Route53-Specific Configuration
AWS Credentials:
- Can be provided via IAM role (recommended) or environment variables
- Required environment variables:
AWS_ACCESS_KEY_IDAWS_SECRET_ACCESS_KEYAWS_REGION(e.g.,"us-east-1")
Hosted Zone ID:
- Provided programmatically to Route53WebsiteDnsManager constructor
- Must match the hosted zone for
EDU_BASE_DOMAIN - Example:
"Z1234567890ABC"
Example .env Configuration
Production Setup:
# Base configuration
EDU_BASE_DOMAIN=solidx.edu
PORTAL_CNAME_DOMAIN=portal.solidx.edu
DNS_PROVIDER=route53
EDU_FRONTEND_UPSTREAM=http://127.0.0.1:3002
# AWS credentials (or use IAM role)
AWS_ACCESS_KEY_ID=AKIA...
AWS_SECRET_ACCESS_KEY=...
AWS_REGION=us-east-1Local Development Setup:
# Base configuration
EDU_BASE_DOMAIN=edu.local
PORTAL_CNAME_DOMAIN=portal.local
DNS_PROVIDER=hosts
EDU_FRONTEND_UPSTREAM=http://localhost:3000Best Practices
Before Activation
-
Validate Configuration
- Verify all required institute fields are filled
- Test payment gateway credentials
- Confirm support contact information is correct
-
Plan Domain Name
- Choose a clear, memorable hosted page prefix
- Verify uniqueness before setting
- Avoid special characters and spaces
-
Test in Staging
- Activate a test institute first
- Verify DNS resolution
- Test portal access
- Check payment flow end-to-end
During Activation
-
Monitor Progress
- Watch for success/error messages
- Check server logs if activation fails
- Verify each step completes successfully
-
Document Configuration
- Record domain name
- Note activation date and user
- Save configuration details
After Activation
-
Verify Infrastructure
- Test DNS resolution from multiple locations
- Check Nginx configuration
- Verify portal accessibility
- Test on multiple devices/browsers
-
Functional Testing
- Login as Institute Admin
- Create a test payment collection
- Verify student portal loads
- Test payment flow (in test mode)
-
Communication
- Notify Institute Admin of activation
- Provide portal URL and credentials
- Share user documentation
- Schedule training if needed
-
Monitoring
- Set up uptime monitoring for the domain
- Monitor server resources (CPU, memory, disk)
- Check error logs regularly
- Track payment transaction success rates
Operational Best Practices
-
Backup Before Changes
- Backup Nginx configuration before bulk activations
- Export institute data before major changes
- Keep DNS records documented
-
Batch Operations
- Activate institutes during low-traffic hours
- Allow time between activations for verification
- Limit concurrent activations to avoid resource exhaustion
-
Documentation
- Maintain list of active institutes and domains
- Document any custom configuration per institute
- Keep activation dates and responsible admin recorded
-
Regular Audits
- Review active institutes monthly
- Check for orphaned Nginx configurations
- Verify DNS records match database status
- Clean up inactive configurations
Troubleshooting Reference
Common Issues and Solutions
Issue: Activation button not visible
- Cause: Status is already "Active" or edit handler not working
- Solution:
- Check current status value
- Verify edit handler is configured in form view
- Check browser console for JavaScript errors
Issue: "PORTAL_CNAME_DOMAIN env var not configured" error
- Cause: Missing required environment variable
- Solution:
- Add
PORTAL_CNAME_DOMAINto.envfile - Restart API server
- Verify value with
echo $PORTAL_CNAME_DOMAIN
- Add
Issue: Nginx reload fails
- Cause: Syntax error in configuration or permission issue
- Solution:
- Run
sudo nginx -tto check syntax - Review generated configuration file
- Check Nginx error logs:
sudo journalctl -u nginx - Verify application has permission to reload Nginx
- Run
Issue: DNS record not created (Route53)
- Cause: Invalid AWS credentials or wrong hosted zone
- Solution:
- Verify AWS credentials are valid
- Check hosted zone ID matches
EDU_BASE_DOMAIN - Confirm IAM permissions include
route53:ChangeResourceRecordSets - Check AWS service status
Issue: Portal returns 502 Bad Gateway
- Cause: Frontend upstream not responding
- Solution:
- Verify frontend service is running
- Check
EDU_FRONTEND_UPSTREAMis correct - Test upstream directly:
curl http://127.0.0.1:3002 - Check frontend logs for errors
Issue: Portal loads but shows wrong content
- Cause: Frontend routing not matching domain to institute
- Solution:
- Verify
hostedPagePrefixis unique - Check frontend routing logic
- Clear browser cache
- Test in incognito/private window
- Verify
Issue: Activation succeeds but portal still inaccessible
- Cause: DNS propagation delay or browser cache
- Solution:
- Wait 10-15 minutes for DNS propagation
- Flush local DNS cache
- Test from different network/location
- Use
nslookupordigto verify DNS
Issue: Cannot deactivate institute
- Cause: Permission issue or configuration locked
- Solution:
- Verify you're logged in as Platform Admin
- Check if there are active payment collections
- Review server logs for specific error
- Try deactivating from API directly (debugging)
Diagnostic Commands
Check DNS Resolution:
# Using nslookup
nslookup stmary.solidx.edu
# Using dig
dig stmary.solidx.edu
# Check CNAME specifically
dig CNAME stmary.solidx.eduCheck Nginx Configuration:
# Test configuration syntax
sudo nginx -t
# View configuration
cat /etc/nginx/sites-available/stmary.solidx.edu.conf
# Check if symlink exists
ls -la /etc/nginx/sites-enabled/ | grep stmary
# Reload Nginx
sudo systemctl reload nginx
# Check Nginx status
sudo systemctl status nginxCheck Application Logs:
# PM2 logs
pm2 logs solid-api --lines 100
# Direct log files
tail -f /var/log/solid-api/error.log
tail -f /var/log/solid-api/combined.logCheck Hosts File (Local):
# View hosts file
cat /etc/hosts
# Search for specific domain
cat /etc/hosts | grep stmary
# Check file permissions
ls -la /etc/hostsTest Portal Access:
# Simple GET request
curl -I http://stmary.solidx.edu
# Full response
curl http://stmary.solidx.edu
# With verbose output
curl -v http://stmary.solidx.edu
# Follow redirects
curl -L http://stmary.solidx.eduSuccess Criteria
You've successfully activated an institute when:
- Status field shows "Active" in database and UI
- "Activate Institute" button is hidden
- "Deactivate Institute" button is visible
- Nginx configuration file exists in sites-available
- Symlink exists in sites-enabled
- DNS CNAME record created and resolving
- Portal accessible at
http://{hostedPagePrefix}-{EDU_BASE_DOMAIN} - Portal loads without errors
- Institute branding appears correctly
- Student portal login page accessible
- Audit trail entry created in Chatter
- Institute Admin notified of activation
Related Documentation
- Institute Onboarding - Complete guide to onboarding new institutes
- Initiate Payment Collection - How to create payment collections after activation
- User Roles & Responsibilities - Understanding platform roles
Frequently Asked Questions
Q: Can I activate multiple institutes at once? A: No, activation must be done one institute at a time through the UI. Bulk activation would require a custom script using the API endpoints.
Q: How long does activation take? A: Typically 5-30 seconds for infrastructure provisioning. DNS propagation can take 5-15 minutes depending on your provider and TTL settings.
Q: Can I change the domain after activation?
A: No, the domain is based on hostedPagePrefix which cannot be changed after activation. You would need to deactivate, change the prefix, and reactivate.
Q: What happens to data when I deactivate? A: All data (students, payments, configuration) remains in the database. Only the infrastructure (Nginx config and DNS) is removed. Reactivating restores access to the same data.
Q: Can Institute Admins activate their own institute? A: No, only Platform Admins have permission to activate/deactivate institutes.
Q: What if activation fails halfway through? A: The system attempts to maintain consistency, but partial failures can occur. Check server logs, clean up manually if needed (remove Nginx config/DNS record), then try again.
Q: Do I need HTTPS/SSL certificates? A: The basic activation creates HTTP configuration. For production, you should configure SSL/TLS certificates (Let's Encrypt recommended) separately.
Q: Can I use a custom domain instead of subdomain? A: The current implementation uses subdomains only. Custom domain support would require code modifications to the DNS and Nginx providers.
Q: How many institutes can I activate? A: No hard limit, but consider server resources (Nginx can handle thousands of virtual hosts) and DNS provider limits.
Q: What are the server requirements for 100 active institutes? A: Nginx overhead is minimal. Main consideration is application server resources. Monitor CPU/memory usage and scale horizontally if needed.
This completes the Activate Institute guide. For questions or issues not covered here, contact the platform development team.