These apps live in separate repositories and are loaded by the core. The core is tiny and most of the work is on the extensions. Similar to kernel vs. drivers.
Why we did that? We've been building custom enterprise data products for almost seven years. Many of these products were so custom we couldn't sell the same product to another client if we wanted. It is not just about code reuse on the function or library level, it's "functionality" refuse as in you plug in a forecast extension, you plug in a sentiment analysis extension, etc.
A couple of years ago, a college acquaintance came to me and asked if he could hire us to deliver a certain product. We practically had the product ready but the features were baked in the product.
So, now, we have features as independent applications that get loaded, displayed, and interacted with easily.
This allows you to decouple functionality and contain instability. It also allows you to add or remove features easily. You want to kill a feature? You don't even have to remove its code. Just don't load it. Maybe you'll need it in the future and you can work on it independently once you sell it.
This also simplifies hiring and is good for retention. The activation energy for a New contributor is dramatically lowered, since they don't have to understand the whole codebase, which takes more time. You can give them one extension to work on.
Retention is improved because there's a path to onboard code wise, and people can start working and be successful from day one and get acquainted with the codebase as they gain experience, extension by extension. They can also take ownership of that extension, which when the company grows can be a business unit or a company in and of itself.
That's in terms of code architecture. This is useful whether you change your sales/product strategy and tactics or not.
Now, there's a difference between a problem and a solution. People usually tell you about their problems in terms of solutions they imagined. Extracting that in terms of "job to be done" and in terms of "what's the underlying problem the client/user/prospect/customer is trying to solve for which they came up with that solution" comes naturally for some, but definitely can be learned.
The answer to "can we have integration with Kafka" is not "sure we'll get right to it" but further inquiring about the workflow and the problem they want to solve. What is the actual workflow, not the one the executive at some company has read in a McKinsey report during breakfast.
Second, did you sell the existing features or not? If not, adding more probably won't solve the problem.
One of the common remarks prospects say is: "solutions x, y, z have that feature" and you want to tell them "and yet here we are". A nicer elicitation question is "what's been your experience with x, y, z". The answer is invariably "we don't use them". A more naive person would have jumped on the occasion and make that feature top priority because the prospect large company has talked about it in the meeting. But that question makes it obvious that even that feature won't make thé sale. You develop it and perpetuate the cycle of wasting time on whimsical demands. The previous question can be followed up with "interesting, what are you using instead/why aren't you using x, y, or z ?"
The point is if that feature or set of feature was that important, they'd probably be no meeting.
One caveat is that certain features truly do matter, and having the above line of questioning will surface those because the answer will "we don't use them because (compliance/security/scalability/etc). For entreprise, it's rarely if ever about price.
Also, the meeting can be to gather more information about your product because they're weighing the pros and cons of developing it internally. They might even have started and are gathering how you did it, especially if they ask questions about your team, how long it took you to build that version of the software, etc.
Again, extract problems not the implementation of the client.
There is an effort to educate the CEO on product building, and on sales too. Ideally, they'd be selling what you already built and you would be prying open business use cases to find underlying problems to build for, and then sell that too.
Ideally, meetings should involve both sales and engineering. The decision to build is taken after the meeting, which is to gather information.
And ideally, the CEO should be selling your existing features of which state you are ashamed, and trying to get a price for them that almost no engineer would dare to ask.