Most organisations already pay for Microsoft 365 and use a fraction of it. SharePoint becomes a file dump, Teams becomes chat, and the workflow and application capability sitting inside the licence goes unused while people ask for new software to solve problems the platform already covers.
We build practical business solutions on the Microsoft stack you are already licensed for.
What We Build
- SharePoint document control — structured libraries, metadata, versioning and permissions that hold up, rather than folders nested nine deep.
- Power Automate workflows — approvals, notifications, routing and system-to-system automation.
- Power Apps — focused internal applications for forms, inspections, requests and field data capture.
- Teams-integrated processes — work that happens where people already are, instead of another portal to remember.
- Dataverse solutions — structured business data when SharePoint lists stop being the right shape.
- Governance — permissions, retention, external sharing and lifecycle, decided deliberately rather than by default.
The Honest Limits
The Microsoft platform is excellent for structured internal workflow and poor at some things people try to force onto it. If a requirement genuinely needs a custom application, complex integration or performance the platform cannot deliver, we will say so rather than building an increasingly fragile Power App and calling it a solution.
Governance Is Where This Usually Fails
Low-code platforms spread quickly and then nobody knows what exists, who owns it, or what breaks when the author leaves. Naming, ownership, environment strategy and permissions are worth deciding at the start — it is far more expensive to impose later.
If you are also considering AI on this stack, Copilot Studio sits naturally alongside this work.
Tell us what your teams are doing manually and we will tell you what Microsoft 365 can genuinely take on.
Related services
- Business Process Automation — Related: business process automation.
Before You Move a File Share Into SharePoint
A file share migration looks like a copy job and behaves like a data project. The folder tree you have today is carrying information: client, year, department, status, whether a document is final or a draft someone abandoned. Lift it across intact and you have reproduced the same problem on a platform built to solve it.
The decision worth making before anything moves is which of those folder levels becomes metadata and which stays structural. Metadata gives you views, filters and retention rules that apply themselves. Structure gives you permission boundaries. Neither choice is permanent, but changing it after people have bookmarked links and built habits costs far more than settling it now.
- Which level of the current tree is genuinely a permission boundary
- What triggers retention or archiving, and who is allowed to delete
- Which content is dead and should be archived instead of migrated
- Who approves the metadata terms so they do not multiply
- How external sharing will work for libraries that clients or subcontractors touch
Where a Power App Stops Being the Right Shape
Power Apps and Dataverse cover a wide band of internal work. They get strained in fairly predictable places: high transaction volume, deeply relational data, external users who should never see a sign-in prompt for your tenant, heavy document generation, and anything that has to stay responsive under sustained load. When a requirement lands in that territory, a custom application or a portal is the right scope, which is what our Web Portals work exists for.
The failure mode here is undramatic. A Power App works in the pilot, gets extended twice, and becomes the thing nobody wants to touch. Watch for that boundary while the design is still on paper.
Licensing Shapes the Design
Organizations with the same product names on the invoice can have different capability available to them. Certain connectors, Dataverse capacity, and some governance and environment controls sit outside a base subscription, and guest access has its own rules. Confirm what your tenant entitles before a design assumes a connector, because a build that leans on a premium connector and a build that avoids one are different builds. That is a question for whoever manages your Microsoft agreement, and it belongs at the start of the design work.
Retention Is Not the Same Thing as Backup
Deleted items sit in recycle bins and preservation holds for a period your tenant configures. That is a retention arrangement, not a restore point you can roll a library back to after a bad migration or an encryption event. Decide what your recovery expectation actually is, write it down, and check it against what your current licensing and tooling provide before the old file server gets switched off.
The same question runs through Teams. Channel messages, private chat and the files behind them live in different places under different settings, so a policy written for document libraries will not automatically cover the conversation where a decision was actually made. Work out which of those records you would need to produce if somebody asked, and configure for that rather than for the default.
Where This Becomes a Real Project
One form, one notification and a list a single department maintains is work someone capable inside the business can usually build, and should. An outside team earns its place when the work crosses departments, touches a system of record, has to survive an audit, or has already been attempted and drifted.
Low-code work also fails quietly when the person who built it moves on. Flows authored under an individual account stop when that account is disabled, and apps with no named owner sit in a shared environment until something breaks and nobody knows who to call. Decide the owner, the environment, the naming convention and the service account arrangement while you are still building, and write it somewhere a new IT manager can find. A documented owner, a place to raise a change request, and a route to test a change before it reaches everyone are what separate a tool from a liability.
Microsoft 365 justifies a real project at the seams: work that starts in Teams and has to end up in your ERP or CRM. That overlaps directly with our CRM and ERP Integration and Business Process Automation work, and the three are usually worth scoping together.
The Order the Work Happens In
Data shape comes first, then the app, then the flows, and the order is not a preference. A Power App form and a Power Automate flow both reference columns by name, and SharePoint fixes a column's internal name at the moment it is created and never changes it afterward. A column created with a typo keeps that typo in every flow expression and every API call long after the display name has been corrected, and a flow that references a column somebody deleted fails at run time rather than at save time.
Before any of that, the current process has to be written down as it actually runs: who touches the record, what state it is in at each hand-off, where it waits, and who is allowed to move it. That part is not a workshop formality. It is where the column list comes from, and it is why discovery reads as tedious to the people going through it.
The exceptions decide the build more than the normal path does. An approval that is rejected ends that run, so a resubmission is a new run with a new approval record and nothing connects the two unless the design stores that link, which matters the first time anyone asks how many requests came back a second time. Concurrency is the other one: a SharePoint list does not lock an item while somebody has it open, so two people editing the same record through a form or an app produces a last write wins result, with the earlier values recoverable only from version history. Those are decisions rather than discoveries, which is why the sequence needs a short and specific set of things from your side.
- One person who can decide the information architecture and stand behind it: column names, the choice terms, and what a single record actually represents. Two people with different mental models produce two schemas inside the same list.
- Real records, including the malformed ones. The request with three attachments and no requester, and the one that skipped a step, shape the validation more than a clean example does.
- The exception paths written out, not just the path that works.
- Approvers named by role, plus what happens when one is on leave. A pending approval stays assigned to the person it was sent to until somebody reassigns it.
- Which existing system is authoritative for each field the process touches, so the build reads from it instead of storing a second copy that drifts away from it.
What to Measure on the Share Before Anyone Plans the Move
A scan of the existing share answers questions a walkthrough cannot, and the numbers routinely change the approach rather than just the schedule.
Path length is the constraint that catches people. SharePoint Online enforces a limit of 400 characters on the entire decoded path including the file name and the site address, so a destination site and library consume part of that budget before your first folder is created. A tree that is legal on a Windows share can arrive with a set of files that cannot be written at all. Names carry their own rules: several characters that are legal on Windows, among them the asterisk, colon, question mark and pipe, are rejected, along with names that begin or end with a period, files beginning with a tilde and dollar sign, and the reserved device names such as CON, PRN, AUX and NUL.
Permissions do not map across one for one either. A deny entry on NTFS has no SharePoint equivalent, and a folder whose access was granted to named individuals rather than groups arrives as a set of unique permission scopes that somebody then maintains by hand. Item counts matter for what comes later: the 5,000 item list view threshold still governs any query not filtered on an indexed column, and that includes queries a Power App or a flow will make against the library months after the move. Before anyone plans the move, these are the numbers worth having from the existing share.
- Longest full path, and the count of paths that will exceed 400 characters once the destination site and library prefix are added.
- Count of files and folders whose names use rejected characters, reserved device names, or a leading or trailing period.
- The largest file, against the 250 GB per file ceiling, plus any extensions your tenant blocks outright.
- How many folders carry permissions that differ from their parent, and how many of those grant access to individual accounts rather than groups.
- Item counts in the largest single folders, measured against the 5,000 threshold.
- The spread of last modified dates, which tells you how much volume each of the decisions above applies to.
What a Flow Does When Nobody Is Watching
A cloud flow leaves less evidence behind than a script on a server. Run history is retained for 28 days, and inside that window it is the only record of what happened: the trigger inputs, each action's output, and the one that failed. A failure noticed in week six has no run left to open. If the process needs a longer record than that, the flow has to write one itself into a list or a table as part of its own design.
Connector actions retry before they give up. The default policy retries a failed action several times with exponential backoff, and a call that timed out on the sending side may already have succeeded on the receiving side, so a downstream system can end up holding the same record twice. Anything that creates a record in another system should look for an existing one first, keyed on a value the calling process controls, rather than assuming the action ran exactly once. Throttling produces the same pattern from the other direction: first-party connectors return HTTP 429 with a Retry-After header when a caller is heavy, and Power Platform applies a daily request limit per user that varies by license.
Notifications about a failing flow go by email to the flow's owner rather than to a support address, and a flow that fails on every run for a sustained period is eventually turned off automatically after those warnings. Monitoring anyone else can see has to be arranged on purpose. The Power Platform admin center shows runs by environment, and a flow can be built to report its own failures into a channel or a list that a team already watches.
Environments, Solutions and What Blocks a Deployment
Where something was built and where it runs should not be the same place, and the mechanism for moving between them is a solution. A Power Platform solution packages apps, flows, tables and their dependencies as one unit: unmanaged in the environment where it is edited, imported as managed where it runs, so the production copy is not casually editable and removing it takes its components with it.
Two pieces make that package portable. Connection references keep the connection out of the flow definition, so an import binds to the target environment's own connection instead of carrying the connection of whoever built it. Environment variables do the same for values that differ between environments, such as a site address or an approver group. Without both, every deployment is a manual rebinding exercise and somebody edits the production site address by hand each time.
Data loss prevention policy is the other thing that stops an import cold. A policy sorts connectors into business, non-business and blocked groups, and a flow that uses connectors from two different groups is not warned, it is suspended. A build that worked in a maker's own environment can fail on its first import into a governed one for that reason alone, which is why the policy in force in the target environment is worth reading at design time rather than at deployment. The default environment complicates this further: every tenant has one, every licensed user is a maker in it, it cannot be deleted, and work built there is the hardest to bring under any of the arrangements above.
Frequently Asked Questions
Is this configuration or software development?
Both, and the split is decided per requirement rather than declared up front. Structured libraries, views, metadata columns, retention settings and permissions are configuration. Power Apps and Power Automate work is development in every sense that matters, with formulas, expressions, error handling and versions, but what it produces lives inside the platform rather than in a codebase you host. There is no server to provision and nothing deployed outside your tenant.
When does a SharePoint list stop being the right shape and Dataverse start?
When relationships between records have to be enforced rather than remembered. A SharePoint list holds a lookup column, but nothing prevents the target item being deleted underneath it, and the SharePoint connector delegates far fewer query operations than the Dataverse one, so a canvas app falls back to retrieving only the first page of rows, 500 by default and 2,000 at most, then filtering in memory. Dataverse adds enforced relationships, row level security and server side rules that apply no matter which client writes. That covers the relational middle ground; the deeply relational, high volume and load sensitive cases named earlier remain custom application or portal scope rather than a Dataverse rebuild.
What access do you need in our tenant?
A maker account in the environment the work is built in, and site collection administrator rights on the sites in scope. A tenant administrator has to be reachable, but only for the things only they can do: creating or assigning an environment, adjusting a data loss prevention policy that blocks a connector the design needs, and consenting to an app registration if an integration requires one. Day to day build work does not need a global administrator account and should not run under one.
Can this connect to our CRM or ERP?
Usually, and the method depends on where that system runs and what it exposes. Dynamics and the other first-party systems have prebuilt connectors. A third-party cloud system with a documented REST API is reached through a custom connector, defined from an OpenAPI description, after which it behaves like any other connector including under data loss prevention policy. A system that exists only inside your network needs an on-premises data gateway installed on a machine that can reach it, which is infrastructure somebody has to own and keep patched.
Can people outside our organization use what you build?
For documents, yes, and the mechanics are routine. A B2B guest invitation creates a user object in your own directory, the guest redeems it and then authenticates against your tenant, and a library or a single folder can be shared with that account the same way it is shared internally. Applications are a separate question, since a guest needs the app shared to them along with the rights behind it. Anonymous access is not part of this at all: a link that works with no sign-in is a different setting with different exposure, controlled at the tenant and site level.
Can a Power App show someone data they are not otherwise allowed to see?
Not on its own. A canvas app connecting directly to a SharePoint list runs those connections as the signed-in user, so it cannot display a record that person could not open in the browser, and hiding a column in the app is presentation rather than security. The elevation path is a flow, because a flow triggered from an app runs under the connections saved with it and can therefore write to a list the app user cannot open. That is a legitimate pattern for something like a request landing in a controlled log, but it should be a decision somebody made rather than a side effect of who happened to build the flow.
We already have flows and apps people built themselves. Do those get rebuilt?
Rarely all of them, and the first step is an inventory rather than a rewrite. The Power Platform admin center lists apps, flows and connections per environment along with their owners, which is often the first time anyone sees the full set. From there, some are adopted as they stand and moved into a solution, some are retired because two of them do the same job under different rules, and a smaller number are rebuilt because they hard-code something that has since changed. Sorting them is a review, not a migration.